靜態(tài)代碼分析_第1頁
靜態(tài)代碼分析_第2頁
靜態(tài)代碼分析_第3頁
靜態(tài)代碼分析_第4頁
靜態(tài)代碼分析_第5頁
已閱讀5頁,還剩11頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、靜態(tài)代碼分析一、什么是靜態(tài)代碼分析靜態(tài)代碼分析是指無需運(yùn)行被測代碼,僅通過分析或檢查源程序的語法、結(jié)構(gòu)、過程、接口等來檢查程序的正確性,找出代碼隱藏的錯(cuò)誤和缺陷,如參數(shù)不匹配,有歧義的嵌套語句,錯(cuò)誤的遞歸,非法計(jì)算,可能出現(xiàn)的空指針引用等等。在軟件開發(fā)過程中,靜態(tài)代碼分析往往先于動(dòng)態(tài)測試之前進(jìn)行,同時(shí)也可以作為制定動(dòng)態(tài)測試用例的參考。統(tǒng)計(jì)證明,在整個(gè)軟件開發(fā)生命周期中,30% 至 70% 的代碼邏輯設(shè)計(jì)和編碼缺陷是可以通過靜態(tài)代碼分析來發(fā)現(xiàn)和修復(fù)的。但是, 由于靜態(tài)代碼分析往往要求大量的時(shí)間消耗和相關(guān)知識(shí)的積累,因此對(duì)于軟件開發(fā)團(tuán)隊(duì)來說,使用靜態(tài)代碼分析工具自動(dòng)化執(zhí)行代碼檢查和分析,能夠極大地

2、提高軟件可靠性并節(jié)省軟件開發(fā)和測試成本。靜態(tài)代碼分析工具的優(yōu)勢幫助程序開發(fā)人員自動(dòng)執(zhí)行靜態(tài)代碼分析,快速定位代碼隱藏錯(cuò)誤和缺陷。幫助代碼設(shè)計(jì)人員更專注于分析和解決代碼設(shè)計(jì)缺陷。顯著減少在代碼逐行檢查上花費(fèi)的時(shí)間,提高軟件可靠性并節(jié)省軟件開發(fā)和測試成本。二、主流Java 靜態(tài)分析工具Findbugs、 checkstyle 和 PMD 都可以作為插件插入eclipse,當(dāng)然也有單獨(dú)的工具可以實(shí)現(xiàn)他們的功能,比如Findbugs Tool 就可以不必插入eclipse 就可以使用。三者的功能如下表:工具目的檢查項(xiàng)FindBugs檢查 .class基于Bug Patterns 概念,查找 javab

3、ytecode( .class文件)中的潛在bug主要檢查bytecode 中的bug patterns , 如 NullPoint 空指針檢查、沒有合理關(guān)閉資源、字符串相同判斷錯(cuò)(=,而不是equals)等PMD 檢查源文件檢查Java源文件中的潛在問題主要包括:空 try/catch/finally/switch 語句塊未使用的局部變量、參數(shù)和private 方法空 if/while 語句過于復(fù)雜的表達(dá)式,如不必要的if 語句等復(fù)雜類CheckStyle主要包括: Javadoc注釋 命名規(guī)范檢查源文件檢查Java源文件是否與代碼多余沒用的Imports主要關(guān)注格規(guī)范相符式Size度量,如

4、過長的方法缺少必要的空格Whitespace重復(fù)代碼三者作為開源的軟件,不用考慮版權(quán)問題。他們的源代碼保存在 HYPERLINK / /上,下載也可以去這里下載。Findbugs 、 checkstyle 、PMD的安裝下載插件因?yàn)镕indbugs、 checkstyle、 PMD 都在 HYPERLINK / / 這個(gè)開源的網(wǎng)站上進(jìn)行管理,所以直接去該網(wǎng)站下載。你可能在sourceforge 上 style,Checksty le HYPERLINK /proj /proj ects/eclipse-c s/files/?sourc e=navbar到 check 但下載下來同樣不能用做 e

5、clpse 插件使用, 注意要下載 eclipsecheckstyleplug-in。我沒有找到可以一下plugins和 features 的文件都下載下來, HYPERLINK /proj /proj只能一個(gè)一個(gè)的下載,然后重新創(chuàng)建了features和PMDects/pmd/file s/pmd-eclipse/update-site-l atest/plugins 文件夾, 然后把東西放 里面。也許有更好的方法吧。同樣注意下載的是 pmd-eclipse 目錄下的文件安裝 eclipse 插件目前來說有三種安裝eclipse 插件的方式:( 1 ) 在線安裝方式:使用 Eclipse的菜單

6、欄Help - SoftwareUpdates - Find and install. -search for new features. -輸入軟件安裝地址進(jìn)行安裝( 2)離線安裝方式一:下載插件文件,將其解壓縮到Eclipse對(duì)應(yīng)的目錄中,即eclipse目錄下對(duì)應(yīng)的features 下和 plugins 下。( 3)離線安裝方式二:links 文件方式。例如 eclipse 的安裝目錄是C:softEclipse3.3 。把插件放在C:eclipsePluginsCheckStyle 下 (文件夾名隨意),如下圖編寫 link 文件放在eclipse 安裝目錄下的links 文件夾內(nèi),如

7、下圖注意事項(xiàng)Checkstyle如果使用eclipse插件版本,需要注意eclipse內(nèi)核版本和jdk 版本。最新 6.x 版本需要jdk1.7,常見的eclipse3.3, MyEclipse8.6 最好用4.x, 5.x版本,具體以能否安裝上為準(zhǔn)。Findbugs簡介 HYPERLINK / /FindBugs 是一個(gè)靜態(tài)分析工具,它檢查類或者JAR 文件,將字節(jié)碼與一組缺陷模式進(jìn)行對(duì)比以發(fā)現(xiàn)可能的問題。有了靜態(tài)分析工具,就可以在不實(shí)際運(yùn)行程序的情況對(duì)軟件進(jìn)行分析。在 FindBugs 的 GUI 中,需要先選擇待掃描的.class文件 (FindBugs 其實(shí)就是對(duì)編譯后的class進(jìn)行

8、掃描,藉以發(fā)現(xiàn)一些隱藏的bug。 )。如果你擁有這些.class檔對(duì)應(yīng)的源文件,可把這些 .java 文件再選上,這樣便可以從稍后得出的報(bào)告中快捷的定位到出問題的代碼上面。此外,還可以選上工程所使用的library,這樣似乎可以幫助FindBugs 做一些高階的檢查,藉以發(fā)現(xiàn)一些更深層的bug。選定了以上各項(xiàng)后,便可以開始檢測了。檢測的過程可能會(huì)花好幾分鐘,具體視工程的規(guī)模而定。檢測完畢可生成一份詳細(xì)的報(bào)告,藉由這份報(bào)告,可以發(fā)現(xiàn)許多代碼中間潛在的bug。比較典型的,如引用了空指針(null pointer dereference), 特定的資源(db connection) 未關(guān)閉, 等等。

9、 如果用人工檢查的方式,這些 bug 可能很難才會(huì)被發(fā)現(xiàn),或許永遠(yuǎn)也無法發(fā)現(xiàn),直到運(yùn)行時(shí)發(fā)作 當(dāng)除掉了這些典型的(classic) bug后, 可以確信的是,我們的系統(tǒng)穩(wěn)定度將會(huì)上一個(gè)新的臺(tái)階。Bug 描述 HYPERLINK /bugDescriptions.html /bugDescriptions.html五、 checkstyle簡介 HYPERLINK / /CheckStyle是 SourceForge下的一個(gè)項(xiàng)目,提供了一個(gè)幫助JAVA開發(fā)人員遵守某些編碼規(guī)范的工具。它能夠自動(dòng)化代碼規(guī)范檢查過程,從而使得開發(fā)人員從這項(xiàng)重要,但是枯燥的任務(wù)中解脫出來。CheckStyle 檢驗(yàn)的主

10、要內(nèi)容Javadoc注釋命名約定標(biāo)題Import 語句體積大小空白修飾符塊代碼問題類設(shè)計(jì)混合檢查(包括一些有用的比如非必須的System.out 和printstackTrace)從上面可以看出,CheckStyle 提供了大部分功能都是對(duì)于代碼規(guī)范的檢查,而沒有提供象PMD 那么多的增強(qiáng)代碼質(zhì)量和修改代碼的功能。但是,對(duì)于團(tuán)隊(duì)開發(fā),尤其是強(qiáng)調(diào)代碼規(guī)范的公司來說,它的功能已經(jīng)足夠強(qiáng)大。Checkstyle 是一款檢查java 程序代碼樣式的工具,可以有效的幫助我們檢視代碼以便更好的遵循代碼編寫標(biāo)準(zhǔn),特別適用于小組開發(fā)時(shí)彼此間的樣式規(guī)范和統(tǒng)一。Checkstyle 提供了高可配置性,以便適用于各

11、種代碼規(guī)范,所以除了可以使用它提供的sun 的代碼標(biāo)準(zhǔn)外,你也可以定制自己的標(biāo)準(zhǔn)。我們可以在eclipse 中安裝 checkstyle 的插件, 來方便我們的使用。Checkstyle 可以讓我們養(yǎng)成書寫良好代碼風(fēng)格的習(xí)慣,代碼的整潔也減少了很多badsmell 的產(chǎn)生。 使用 checkstyle 的過程中可能需要經(jīng)常的調(diào)整配置文件,有些 check 過于嚴(yán)格,可以根據(jù)實(shí)際情況取消一些代碼檢查。CheckStype 的配置詳解Checkstyle 配置是通過指定modules 來應(yīng)用到j(luò)ava 文件的。modules 是樹狀結(jié)構(gòu),以一個(gè)名為 Checker 的 module 作為 root

12、 節(jié)點(diǎn),一般的checker 都會(huì)包括TreeWalker 子 module 。我們可以參照checkstyle 中的 sun_checks.xml,這是根據(jù)sun的 java語言規(guī)范寫的配置。在 xml 配置文件中通過module 的 name 屬性來區(qū)分module , module 的 Properties 可以控制如何去執(zhí)行這個(gè)module,每個(gè) property 都有一個(gè)默認(rèn)值,所有的check 都有一個(gè)severity屬性, 用它來指定check 的 level。 TreeWalker 為每個(gè) java 文件創(chuàng)建一個(gè)語法樹,在節(jié)點(diǎn)之間調(diào)用 submodules 的 Checks。下

13、面來看看standard checks 中的一些具體用法。Javadoc Commentsl JavadocPackage檢查每個(gè)java package中是否有java 注釋文件,默認(rèn)是允許一個(gè)package-info.java, 也可以通過 allowLegacy 屬性配置允許package.html 。lJavadocType檢查類和接口的javadoc。默認(rèn)不檢查author 和 version tags。lJavadocMethod檢查方法和構(gòu)造函數(shù)的javadoc。默認(rèn)不檢查未使用的異常拋出。lJavadocVariable檢查變量的javadoc。lJavadocStyle檢查

14、javadoc 的格式。比如:javadoc 的第一行是否以句號(hào)結(jié)束,javadoc 除了 tags 外是否有description ,檢查 javadoc 中的 html 格式。l WriteTag輸出 javadoc 中的 tag。Naming Conventionsl AbstractClassName檢查抽象類名。l ClassTypeParameterName檢查類的Parameter 名。lConstantName檢查常量名。lLocalFinalVariableName檢查局部的final 類型變量名,包括catch 的參數(shù)。lLocalVarableName檢查局部的非fina

15、l 類型的變量名,包括catch 的參數(shù)。lMemberName檢查非靜態(tài)變量。l MethodName檢查方法名。lMethodTypeParameterName檢查方法的參數(shù)名。lPackageName檢查包名。lParameterName檢查參數(shù)名。lStaticVariableName檢查靜態(tài)的,非final 類型的變量名。lTypeName檢查類名和接口名。Importsl AvoidStarImport檢查是否有使用* 進(jìn)行import 。lAvoidStaticImport檢查是否有靜態(tài)import 。比如是否導(dǎo)入了java.lang 包中的內(nèi)容。lIllegalImport檢查

16、是否import 了違法的包。默認(rèn)拒絕import 所有 sun.*包。lRedundanImport檢查是否有重復(fù)的import 。lUnusedImports檢查是否有未使用的import 。lImportOrder檢查 import 的分組和順序。lImportControl控制可 import 的包。在一個(gè)較大的project 可限制使用過多的第三方包,通過一個(gè)依照 HYPERLINK /dtds/import_control_1_0.dtd /dtds/import_control_1_0.dtd 的 xml 文件來指定。Size Violationsl ExecutableStat

17、ementCount TOC o 1-5 h z 限制可執(zhí)行代碼片段的長度。默認(rèn)為30。lFileLength檢查 java 文件的長度。默認(rèn)為2000。lLineLength檢查代碼行的長度。默認(rèn)為80。lMethodLength檢查方法和構(gòu)造函數(shù)的長度。默認(rèn)為150。lAnonInnerLength檢查匿名內(nèi)部類的長度。默認(rèn)為20。7。l ParameterNumber 7。Whitespacel GenericWhitespace檢查和 周圍的空白。l EmptyForInitializerPad檢查空的初始化位置的空白。比如for 循環(huán)中的初始化。lEmptyForIteratorPa

18、d檢查空的迭代位置的空白。lMethodParamPad檢查方法簽名之前的空白。lNoWhitespaceAfter檢查分隔符后的空白。lNoWhitespaceBefore檢查分隔符前的空白。lOperatorWrap檢查操作符的空白規(guī)則。lParenPad檢查圓括號(hào)的空白規(guī)則。lTypecaseParenPad檢查強(qiáng)制轉(zhuǎn)型的圓括號(hào)的空白規(guī)則。lTabCharacter檢查是否有Tab字符( )。t lWhitespaceAfter檢查分隔符是否在空白之后。lWhitespaceAround檢查分隔符周圍是否有空白。ModifierOrderlModifierOrder檢查修飾符的順序是否遵

19、照java 語言規(guī)范。lRedundantModifier檢查接口和annotation 中是否有重復(fù)的修飾符。Block Checksl EmptyBlock檢查空的代碼塊。lLeftCurly檢查 和左邊的代碼塊是否在同一行。 , lNeedBraces檢查是否需要大括號(hào)。主要是在if, else 時(shí)的情況。lRightCurly檢查 。- lAvoidNestedBlocks檢查不需要的嵌套 ,。 - Codingl ArrayTrailingComma檢查數(shù)組初始化是否以逗號(hào)結(jié)束。lAvoidInlineConditionals檢查 inline 的條件操作。lCovariantEqu

20、als檢查類是否覆蓋了equals(java.lang.Object) 。lDoubleCheckedLocking檢查DCL的問題。lEmptyStatement檢查空的代碼段。lEqualsAvoidNull檢查一個(gè)可能為null 的字符串是否在equals()比較的左邊。lEqualsHashCode檢查類是否覆蓋了equals()和 hashCode()。lFinalLocalVariable檢查未改變過的局部變量是否聲明為final 。lHiddenField檢查局部變量或參數(shù)是否隱藏了類中的變量。lIllegalInstantiation檢查是否使用工廠方法實(shí)例化。lIllegal

21、Token檢查非法的分隔符。lIllegalTokenText檢查非法的分隔符的下個(gè)字符。lInnerAssignment檢查子表達(dá)式中是否有賦值操作。lMagicNumber檢查是否有“magic numbers”。lMissingSwitchDefault檢查 switch 語句是否有default 的 clause。lModifiedControlVariable檢查循環(huán)控制的變量是否在代碼塊中被修改。lRedundantThrows檢查是否有被重復(fù)拋出的異常。lSimplifyBooleanExpression檢查是否有過度復(fù)雜的布爾表達(dá)式。lSimplifyBooleanReturn

22、檢查是否有過于復(fù)雜的布爾返回代碼段。l StringLiteralEquality檢查字符串是否有用= =或 !=進(jìn)行操作。lNestedIfDepth檢查嵌套的層次深度。lNestedTryDepth檢查 try 的層次深度。lNoClone檢查是否覆蓋了clone()。lNoFinalizer檢查是否有定義finalize()。lSuperClone檢查覆蓋的clone() 是否有調(diào)用super.clone()。lSuperFinalize檢查覆蓋的finalize()是否有調(diào)用super.finalize()。lIllegalCatch檢查是否catch 了不能接受的錯(cuò)誤。lIllega

23、lThrows檢查是否拋出了未聲明的異常。lPackageDeclaration檢查類中是否有聲明package。lJUnitTestCase確保setUp(), tearDown() 方法簽名的正確性。lReturnCount限制return 代碼段的數(shù)量。lIllegalType檢查未使用過的類。lDeclarationOrder檢查類和接口中的聲明順序。lParameterAssignment檢查不允許的參數(shù)賦值。lExplicitInitialization檢查類和對(duì)象成員是否初始化為默認(rèn)值。lDefaultComesLast檢查 default 的 clause 是否在 switch

24、 代碼段的最后。lMissingCtor檢查類依賴。lFallThrough檢查 switch 代碼的 case中是否缺少break, return , throw 和 continue 。lMultipleStringLiterals檢查一個(gè)文件中是否有多次出現(xiàn)的字符串。lMultipleVariableDeclarations檢查代碼段和代碼行中是否有多次變量聲明。lRequireThis檢查代碼中是否有“this.l UnnecessaryParentheses檢查是否有使用不需要的圓括號(hào)。Class DesignlVisibilityModifier檢查類成員的可見度。lFinalCl

25、ass檢查只有private 構(gòu)造函數(shù)的類是否聲明為finallInterfaceIsType檢查接口是否僅定義類型。lHideUtilityClassConstructor檢查工具類是否有putblic 的構(gòu)造器。lDesignForExension檢查類是否為擴(kuò)展設(shè)計(jì)。lMutableException確保異常是不可變的。lThrowsCount限制拋出異常的數(shù)量。Duplicate Codel StrictDuplicateCode嚴(yán)格檢查重復(fù)代碼。Miscellaneousl GenericIllegalRegexp正則表達(dá)式的模式檢查。lNewlineAtEndOfFile檢查文件是

26、否以一個(gè)空行結(jié)束。lTodoComment檢查TODO:注釋。lTranslation檢查property 文件中是否有相同的key。lUncommentedMain檢查是否有未注釋的main 方法。lUpperEll檢查 long 型約束是否有大寫的“L”。lArrayTypeStyle檢查數(shù)組類型定義的樣式。lFinalParametersfinal 的。檢查方法名、構(gòu)造函數(shù)、catch final 的。lIndentation檢查代碼中正確的縮進(jìn)。lTrailingComment確保是否要代碼行注釋。l RequiredRegexp確保一個(gè)指定的正則表達(dá)式的規(guī)則已經(jīng)存在代碼中。Check

27、style 常見的錯(cuò)誤提示Type is missing a javadoc commentClass缺少類型說明“ , ” should be on the previous line“ , ” 應(yīng)該位于前一行Methods is missing a javadoc comment方法前面缺少javadoc 注釋Expected throws tag for “ Exception 在注釋中希望有throws 的說明“ . ” Is preceeded with whitespace前面不能有空格“ . ” Is followed by whitespace“ .后面不能有空格“ =” is

28、 not preceeded with whitespace“ =” 前面缺少空格“ =” is not followed with whitsepace“ =” 后面缺少空格“ - ” should be on the same line“ - ” 應(yīng)該與下條語句位于同一行Unused param tag for “ unused ”沒有參數(shù)“ unused,不需注釋”Variable “ CA” missing javadoc變量 “ CA缺少”javadoc 注釋Line longer than 80characters行長度超過80Line contains a tab charact

29、er行含有” tab ” 字符Redundant “ Public ” modifier冗余的“ public ” modifierFinal modifier out of order with the JSLsuggestionFinal modifier 的順序錯(cuò)誤Avoid using the “ .* ” form of importImport 格式避免使用“ .* ”Redundant import from the same package從同一個(gè)包中Import 內(nèi)容Unused import-java.util.listImport 進(jìn)來的java.util.list 沒有

30、被使用Duplicate import to line 13重復(fù) Import 同一個(gè)內(nèi)容Import from illegal package從非法包中Import 內(nèi)容“ while ” construct must use “ ,- ”“ while 語句缺少 ”“ ,- ”Variable “ sTest1 ” must be private and have accessor method變量 “ sTest1應(yīng)該是 ” private 的,并且有調(diào)用它的方法Variable “ ABC” must match pattern- za-zA-“Z0-*9a+*$ ”變量 “ ABC”

31、不符合命名規(guī)則“ *a-za-zA-Z0-9+*$”“ ( ” is followed by whitespace“ ( 后 面不能有”空格“ ) ” is proceeded by whitespace“ ) 前 面不能有”空格六、 PMD簡介 HYPERLINK https:/pmd.github.io/ https:/pmd.github.io/PMD 是一種開源分析Java代碼錯(cuò)誤的工具。與其他分析工具不同的是,PMD 通過靜態(tài)分析獲知代碼錯(cuò)誤。也就是說,在不運(yùn)行Java程序的情況下報(bào)告錯(cuò)誤。PMD 附帶了許多可以直接使用的規(guī)則,利用這些規(guī)則可以找出Java源程序的許多問題,例如:? 潛在的bug:空的try/catch/finally/switch 語句? 未使用的代碼:未使用的局部變量、參數(shù)、私有方法等? 可選的代碼:String/StringBuffer 的濫用? 復(fù)雜的表達(dá)式:不必須的if 語句、可以使用while 循環(huán)完成的for 循環(huán)? 重復(fù)的代碼:拷貝/粘貼代碼意味著拷貝/粘貼 bugs? 循環(huán)體創(chuàng)建新對(duì)象:盡量不要再for 或 while 循環(huán)體內(nèi)實(shí)例化一個(gè)新對(duì)象 資源關(guān)閉:Connect, Result, Statement 等使用之后確保關(guān)閉掉此外,用戶還可以自己定義規(guī)則,檢查Jav

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論