六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

用PMD自動執(zhí)行Java代碼靜態(tài)區(qū)分

[摘要]作者:仙人掌工作室   一、基礎(chǔ)知識   PMD是一種分析Java代碼錯誤的工具。與其他分析工具不同的是,PMD通過靜態(tài)分析獲知代碼錯誤。也就是說,在不運行Java程序的情況下報告錯誤。PMD附帶了...
作者:仙人掌工作室

  一、基礎(chǔ)知識

  PMD是一種分析Java代碼錯誤的工具。與其他分析工具不同的是,PMD通過靜態(tài)分析獲知代碼錯誤。也就是說,在不運行Java程序的情況下報告錯誤。PMD附帶了許多可以直接使用的規(guī)則,利用這些規(guī)則可以找出Java源程序的許多問題,例如沒有用到的變量、多余的變量創(chuàng)建操作、空的catch塊,等等。此外,用戶還可以自己定義規(guī)則,檢查Java代碼是否符合某些特定的編碼規(guī)范。例如,你可以編寫一個規(guī)則,要求PMD找出所有創(chuàng)建Thread和Socket對象的操作。

  最初,PMD是為了支持Cougaar項目而開發(fā)的。Cougaar是美國國防高級研究計劃局(Defense Advanced Research Projects Agency,DARPA)的一個項目。DARPA開放了PMD的源代碼,所以PMD被發(fā)布到了SourceForge網(wǎng)站上。不久前,PMD的下載次數(shù)就超過了14000次,頁面瀏覽次數(shù)超過了130000次。更重要的是,在源代碼開放作者的努力下,越來越多的PMD規(guī)則和IDE插件被開發(fā)出來,然后加入到了PMD的核心項目之中。

  你可以從PMD的網(wǎng)站下載PMD的二進制版本,或下載帶源代碼的版本,下載得到的都是ZIP文件。假設(shè)你下載了二進制版本,先把它解壓縮到任意一個目錄。接下來怎么做,就要看你準備怎么用它——最簡單的,如果要在一個Java源代碼目錄中運行PMD,只需直接在命令行上運行下面的命令:

C:\data\pmd\pmd>java -jar lib\pmd-1.02.jar c:\j2sdk1.4.1_01\src\java\util
   text rulesets/unusedcode.xml



  輸出結(jié)果類如:

c:\j2sdk1.4.1_01\src\java\util\AbstractMap.java 650
    Avoid unused local variables such as 'v'    
c:\j2sdk1.4.1_01\src\java\util\Date.java        438  
    Avoid unused local variables such as 'millis'



  除了直接在命令行上運行PMD之外,還可以通過Ant、Maven或者各種集成開發(fā)環(huán)境(IDE)運行PMD,例如jEdit、Netbeans、Eclipse、Emacs、IDEAJ和JBuilder等。

  二、內(nèi)建規(guī)則

  PMD本身就附帶了許多規(guī)則。下面是幾個例子。

沒有用到的代碼顯然是應(yīng)該被清除的。
public class Foo {
   // 下面這個實例變量沒有用到
   private List bar = new ArrayList(500);
}
如果用一個接口也能達到同樣的目標,為什么要返回一個具體的類?例如,下例可以改用List接口。
public ArrayList getList() {
   return new ArrayList();
}
當(dāng)if的條件為真時,if代碼塊其實不做任何事情。下面這段代碼其實可以寫得更加簡潔一些。
public void doSomething(int y) {
   if (y >= 2) {
   } else {
      System.out.println("Less than two");
   }
}
為什么要創(chuàng)建一個新的String對象?只要改用String x="x"就可以了。
String x = new String("x");



  PMD還包含其他許多內(nèi)建規(guī)則,但從上面幾個例子已經(jīng)可以看出PMD的基本工作方式。只要定義適當(dāng)?shù)撵o態(tài)規(guī)則,PMD就可以象一個富有經(jīng)驗的程序員那樣,幫你指出代碼存在的問題。

  三、工作原理

  PMD的核心是JavaCC解析器生成器。PMD結(jié)合運用JavaCC和EBNF(擴展巴科斯-諾爾范式,Extended Backus-Naur Formal)語法,再加上JJTree,把Java源代碼解析成抽象語法樹(AST,Abstract Syntax Tree)。顯然,這句話不那么好懂,且看下文具體說明。

  從根本上看,Java源代碼只是一些普通的文本。不過,為了讓解析器承認這些普通的文本是合法的Java代碼,它們必須符合某種特定的結(jié)構(gòu)要求。這種結(jié)構(gòu)可以用一種稱為EBNF的句法元語言表示,通常稱為“語法”(Grammar)。JavaCC根據(jù)語法要求生成解析器,這個解析器就可以用于解析用Java編程語言編寫的程序。

  不過實際運行中的PMD還要經(jīng)過JJTree的一次轉(zhuǎn)換。JJTree是一個JavaCC的插件,通過AST擴充JavaCC生成的解析器。AST是一個Java符號流之上的語義層。有了JJTree,語法分析的結(jié)果不再是“System, ., out, ., . println”之類的符號序列,而是一個由對象構(gòu)成的樹型層次結(jié)構(gòu)。例如,下面是一段簡單的Java代碼以及與之對應(yīng)的AST。

Java源代碼:
public class Foo {
    public void bar() {
        System.out.println("hello world");
    }
}
對應(yīng)的抽象語法樹
CompilationUnit
TypeDeclaration
  ClassDeclaration
   UnmodifiedClassDeclaration
    ClassBody
     ClassBodyDeclaration
      MethodDeclaration
       ResultType
       MethodDeclarator
        FormalParameters
       Block
        BlockStatement
         Statement
          StatementExpression
           PrimaryExpression
            PrimaryPrefix
             Name
            PrimarySuffix
             Arguments
              ArgumentList
               Expression
                PrimaryExpression
                 PrimaryPrefix
                  Literal



  四、編寫規(guī)則

  前面我們看到了Java源代碼以及與之對應(yīng)的對象層次結(jié)構(gòu)。下面我們就要利用這些對象編寫PMD規(guī)則檢查代碼存在的問題。

  一般地,一個PMD規(guī)則可以看成一個Visitor,它遍歷AST,尋找多個對象之間的一種特定模式,這種模式表示代碼存在的問題。問題模式可能簡單也可能復(fù)雜,簡單的如查找代碼中是否包含new Thread關(guān)鍵詞,復(fù)雜的如確定一個類是否正確覆蓋了equals和hashcode。

  下面是一個尋找空if語句的簡單PMD規(guī)則。

//擴展AbstractRule,以啟用Visitor模式
public class EmptyIfStmtRule extends AbstractRule implements Rule {
   //當(dāng)源代碼中出現(xiàn)一個Block,下面的方法被調(diào)用
   public Object visit(ASTBlock node, Object data){
      //如果父節(jié)點是一個if語句且代碼塊里面沒有任何內(nèi)容
      if ((node.jjtGetParent().jjtGetParent() instanceof ASTIfStatement)
         && node.jjtGetNumChildren()==0) {
         //肯定代碼存在問題。把一個RuleViolation加入到Report。
         RuleContext ctx = (RuleContext)data;
         ctx.getReport().addRuleViolation(createRuleViolation(ctx,
            node.getBeginLine()));
      }
      //繼續(xù)檢查樹的下一個節(jié)點
      return super.visit(node, data);
   }
}



  也許你不能一下子掌握這段代碼,其實它的思路還是比較簡單的:

  #擴展AbstractRule基類。

  #聲明一個“鉤子”,一旦我們感興趣的節(jié)點出現(xiàn),它就會被調(diào)用(稱為“回調(diào)”)。在上面的例子中,我們要求在每一個ASTBlock出現(xiàn)時得到通知,所以聲明visit(ASTBlock node, Object data)。

  #在回調(diào)函數(shù)中,判斷是否出現(xiàn)了我們正在檢查的問題。本例我們檢查是否存在空的if塊,所以先判斷當(dāng)前是否在ASTIfStatement之內(nèi),然后判斷它是否有子節(jié)點。

  當(dāng)然,我們還可以按照另一種方法進行檢查:聲明一個要求檢查ASTIfStatement的回調(diào)函數(shù),然后在回調(diào)函數(shù)中檢查是否存在子節(jié)點。

  五、配置規(guī)則

  寫好自定義規(guī)則之后,接下來要把它加入到某個PMD規(guī)則集。所謂PMD規(guī)則集,就是由一組PMD規(guī)則構(gòu)成的集合。每個PMD規(guī)則集由一個XML文件定義,下面是一個PMD規(guī)則的配置信息的例子:

<rule name="EmptyIfStmt"
   message="避免使用空的if語句"
   class="net.sourceforge.pmd.rules.EmptyIfStmtRule">
   <description>
      找到空的if語句:if檢查了條件,但if塊里面沒有任何內(nèi)容。
   </description>
   <priority>3</priority>
   <example>
      <![CDATA[
         if (absValue < 1) {
            // not good
         }
      </XMLCDATA>
   </example>
</rule>



  可以看出,規(guī)則配置文件包含了許多有用的信息。要運行新添加的規(guī)則,只需把規(guī)則集XML文件和Java源代碼文件放入CLASSPATH,然后運行PMD。

  結(jié)束語:本文介紹了PMD如何在不編譯代碼的情況下分析和尋找代碼存在的問題,通過幾個簡單的例子了解了EBNF語法、JavaCC和AST,以及如何用PMD檢查代碼存在的問題、如何編寫和運用定制PMD規(guī)則等。愿PMD能夠助你一臂之力!  


主站蜘蛛池模板: 亚洲精品播放 | 视频在线精品 | 色婷婷综合和线在线 | 日韩在线视频播放 | 日韩精品国产自在欧美 | 天天干天天操天天拍 | 一级女性全黄久久生活片免费 | 日日天干夜夜人人添 | 特黄十八岁大片 | 午夜影视在线观看 | 婷婷春色 | 欧美视频中文字幕 | 中文字幕国产 | 亚洲天堂一区二区 | 亚洲成人高清在线 | 四虎在线视频免费观看视频 | 天天噜噜揉揉狠狠夜夜 | 中文字幕第30页 | 天天草比| 四虎免费永久在线播放 | 中文字幕在线视频不卡 | 色综合久久中文字幕综合网 | 天天干天天爱天天操 | 一级香蕉视频在线观看 | 色噜噜在线 | 亚洲国产精品高清在线一区 | 天天干天天干天天干天天 | 亚洲精品视频在线观看你懂的 | 亚洲日韩在线视频 | 影音先锋大型av资源 | 在线播放国产色视频在线 | 亚洲乱码在线视频 | 四虎院影永久在线观看 | 中文字幕欧美成人免费 | 亚洲视频日韩视频 | 碰91精品国产91久久婷婷 | 日韩理论 | 色综合色狠狠天天久久婷婷基地 | 午夜在线亚洲男人午在线 | 欧美一级美片在线观看免费 | 色网站在线播放 |