乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      用PMD自動(dòng)執(zhí)行Java代碼靜態(tài)分析

       左目右于 2011-08-28
      一、基礎(chǔ)知識(shí)
        PMD是一種分析Java代碼錯(cuò)誤的工具。與其他分析工具不同的是,PMD通過靜態(tài)分析獲知代碼錯(cuò)誤。也就是說,在不運(yùn)行Java程序的情況下報(bào)告錯(cuò)誤。PMD附帶了許多可以直接使用的規(guī)則,利用這些規(guī)則可以找出Java源程序的許多問題,例如沒有用到的變量、多余的變量創(chuàng)建操作、空的catch塊,等等。此外,用戶還可以自己定義規(guī)則,檢查Java代碼是否符合某些特定的編碼規(guī)范。例如,你可以編寫一個(gè)規(guī)則,要求PMD找出所有創(chuàng)建Thread和Socket對(duì)象的操作。
        最初,PMD是為了支持Cougaar項(xiàng)目而開發(fā)的。Cougaar是美國國防高級(jí)研究計(jì)劃局(Defense Advanced Research Projects Agency,DARPA)的一個(gè)項(xiàng)目。DARPA開放了PMD的源代碼,所以PMD被發(fā)布到了SourceForge網(wǎng)站上。不久前,PMD的下載次數(shù)就超過了14000次,頁面瀏覽次數(shù)超過了130000次。更重要的是,在源代碼開放作者的努力下,越來越多的PMD規(guī)則和IDE插件被開發(fā)出來,然后加入到了PMD的核心項(xiàng)目之中。
        你可以從PMD的網(wǎng)站下載PMD的二進(jìn)制版本,或下載帶源代碼的版本,下載得到的都是ZIP文件。假設(shè)你下載了二進(jìn)制版本,先把它解壓縮到任意一個(gè)目錄。接下來怎么做,就要看你準(zhǔn)備怎么用它——最簡單的,如果要在一個(gè)Java源代碼目錄中運(yùn)行PMD,只需直接在命令行上運(yùn)行下面的命令:
      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'
        除了直接在命令行上運(yùn)行PMD之外,還可以通過Ant、Maven或者各種集成開發(fā)環(huán)境(IDE)運(yùn)行PMD,例如jEdit、Netbeans、Eclipse、Emacs、IDEAJ和JBuilder等。
        二、內(nèi)建規(guī)則
        PMD本身就附帶了許多規(guī)則。下面是幾個(gè)例子。
      沒有用到的代碼顯然是應(yīng)該被清除的。
      public class Foo {
      // 下面這個(gè)實(shí)例變量沒有用到
      private List bar = new ArrayList(500);
      }
      如果用一個(gè)接口也能達(dá)到同樣的目標(biāo),為什么要返回一個(gè)具體的類?例如,下例可以改用List接口。
      public ArrayList getList() {
      return new ArrayList();
      }
      當(dāng)if的條件為真時(shí),if代碼塊其實(shí)不做任何事情。下面這段代碼其實(shí)可以寫得更加簡潔一些。
      public void doSomething(int y) {
      if (y >= 2) {
      } else {
      System.out.println("Less than two");
      }
      }
      為什么要?jiǎng)?chuàng)建一個(gè)新的String對(duì)象?只
      要改用String x="x"就可以了。
      String x = new String("x");
       
        PMD還包含其他許多內(nèi)建規(guī)則,但從上面幾個(gè)例子已經(jīng)可以看出PMD的基本工作方式。只要定義適當(dāng)?shù)撵o態(tài)規(guī)則,PMD就可以象一個(gè)富有經(jīng)驗(yàn)的程序員那樣,幫你指出代碼存在的問題。
        三、工作原理
        PMD的核心是JavaCC解析器生成器。PMD結(jié)合運(yùn)用JavaCC和EBNF(擴(kuò)展巴科斯-諾爾范式,Extended Backus-Naur Formal)語法,再加上JJTree,把Java源代碼解析成抽象語法樹(AST,Abstract Syntax Tree)。顯然,這句話不那么好懂,且看下文具體說明。
        從根本上看,Java源代碼只是一些普通的文本。不過,為了讓解析器承認(rèn)這些普通的文本是合法的Java代碼,它們必須符合某種特定的結(jié)構(gòu)要求。這種結(jié)構(gòu)可以用一種稱為EBNF的句法元語言表示,通常稱為“語法”(Grammar)。JavaCC根據(jù)語法要求生成解析器,這個(gè)解析器就可以用于解析用Java編程語言編寫的程序。
        不過實(shí)際運(yùn)行中的PMD還要經(jīng)過JJTree的一次轉(zhuǎn)換。JJTree是一個(gè)JavaCC的插件,通過AST擴(kuò)充JavaCC生成的解析器。AST是一個(gè)Java符號(hào)流之上的語義層。有了JJTree,語法分析的結(jié)果不再是“System, ., out, ., . println”之類的符號(hào)序列,而是一個(gè)由對(duì)象構(gòu)成的樹型層次結(jié)構(gòu)。例如,下面是一段簡單的Java代碼以及與之對(duì)應(yīng)的AST。
      Java源代碼:
      public class Foo {
      public void bar() {
      System.out.println("hello world");
      }
      }
      對(duì)應(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源代碼以及與之對(duì)應(yīng)的對(duì)象層次結(jié)構(gòu)。下面我們就要利用這些對(duì)象編寫PMD規(guī)則檢查代碼存在的問題。
        一般地,一個(gè)PMD規(guī)則可以看成一個(gè)Visitor,它遍歷AST,尋找多個(gè)對(duì)象之間的一種特定模式,這種模式表示代碼存在的問題。問題模式可能簡單也可能復(fù)雜,簡單的如查找代碼中是否包含new Thread關(guān)鍵詞,復(fù)雜的如確定一個(gè)類是否正確覆蓋了equals和hashcode。
        下面是一個(gè)尋找空if語句的簡單PMD規(guī)則。
      //擴(kuò)展AbstractRule,以啟用Visitor模式
      public class EmptyIfStmtRule extends AbstractRule implements Rule {
      //當(dāng)源代碼中出現(xiàn)一個(gè)Block,下面的方法被調(diào)用
      public Object visit(ASTBlock node, Object data){
      //如果父節(jié)點(diǎn)是一個(gè)if語句且代碼塊里面沒有任何內(nèi)容
      if ((node.jjtGetParent().jjtGetParent() instanceof ASTIfStatement)
      && node.jjtGetNumChildren()==0) {
      //肯定代碼存在問題。把一個(gè)RuleViolation加入到Report。
      RuleContext ctx = (RuleContext)data;
      ctx.getReport().addRuleViolation(createRuleViolation(ctx,
      node.getBeginLine()));
      }
      //繼續(xù)檢查樹的下一個(gè)節(jié)點(diǎn)
      return super.visit(node, data);
      }
      }
        也許你不能一下子掌握這段代碼,其實(shí)它的思路還是比較簡單的:
        #擴(kuò)展AbstractRule基類。
        #聲明一個(gè)“鉤子”,一旦我們感興趣的節(jié)點(diǎn)出現(xiàn),它就會(huì)被調(diào)用(稱為“回調(diào)”)。在上面的例子中,我們要求在每一個(gè)ASTBlock出現(xiàn)時(shí)得到通知,所以聲明visit(ASTBlock node, Object data)。
        #在回調(diào)函數(shù)中,判斷是否出現(xiàn)了我們正在檢查的問題。本例我 們檢查是否存在空的if塊,所以先判斷當(dāng)前是否在ASTIfStatement之內(nèi),然后判斷它是否有子節(jié)點(diǎn)。
        當(dāng)然,我們還可以按照另一種方法進(jìn)行檢查:聲明一個(gè)要求檢查ASTIfStatement的回調(diào)函數(shù),然后在回調(diào)函數(shù)中檢查是否存在子節(jié)點(diǎn)。
        五、配置規(guī)則
        寫好自定義規(guī)則之后,接下來要把它加入到某個(gè)PMD規(guī)則集。所謂PMD規(guī)則集,就是由一組PMD規(guī)則構(gòu)成的集合。每個(gè)PMD規(guī)則集由一個(gè)XML文件定義,下面是一個(gè)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ī)則配置文件包含了許多有用的信息。要運(yùn)行新添加的規(guī)則,只需把規(guī)則集XML文件和Java源代碼文件放入CLASSPATH,然后運(yùn)行PMD。
        結(jié)束語:本文介紹了PMD如何在不編譯代碼的情況下分析和尋找代碼存在的問題,通過幾個(gè)簡單的例子了解了EBNF語法、JavaCC和AST,以及如何用PMD檢查代碼存在的問題、如何編寫和運(yùn)用定制PMD規(guī)則等。愿PMD能夠助你一臂之力!
      文章出處:飛諾網(wǎng)(www.):http://www./course/3_program/java/javaxl/20100630/290433.html

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多