介紹
CheckStyle是SourceForge下的一個項目,提供了一個幫助JAVA開發人員遵守某些編碼規范的工具。它能夠自動化代碼規范檢查過程,從 而使得開發人員從這項重要,但是枯燥的任務中解脫出來。
CheckStyle默認提供一下主要檢查內容:
•Javadoc注釋
•命名約定
•標題
•Import語句
•體積大小
•空白
•修飾符
•塊
•代碼問題
•類設計
•混合檢查(包活一些有用的比如非必須的 System.out和printstackTrace)
從上面可以看出,CheckStyle提供了大部分功能都是對于代碼規范 的檢查,而沒有提供象PMD和Jalopy那么多的增強代碼質量和修改代碼的功能。但是,對于團隊開發,尤其是強調代碼規范的公司來說,它的功能已經足夠強大。
Eclipse插件安裝和使用
步驟一:http://sourceforge.net/projects/checkclipse/下載checkstyle的eclipse插件checkclipse。下載后,將包放入eclipse的plugins文件夾下,然后重啟eclipse。在Windows—>preferences下找到checkclipse。如下圖:
勾選Set Project Dir as Checkjstyle Basedir
步驟二:右鍵選中你要進行checkstyle的項目文件,選擇“properties”。如下圖:
勾選Enable Checkstyle和Set Project ClassLoader.
然后再Checkstyle Configuraion File中選擇項目中checkstyle的配置文件。這里我把配置文件時放置在項目根目錄下,所以點擊右側“Browse”按鈕,在項目根目錄下選擇該文件。按“OK”按鈕。
這樣整個項目的代碼將根據配置文件中設置的原則進行出錯提示.結果如下圖:
由圖可知對不符合代碼規范的代碼會有錯誤提示,并且有提示信息。
Maven插件安裝和使用
首先,修改要檢查代碼庫top級的pom.xml文件,在build部分配置CheckStyle的Maven插件,以便于下載安裝對應版本的插件(Maven會自動從其鏡像庫中下載),方法如下:
- <project>
- ...
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <version>2.3</version>
- </plugin>
- </plugins>
- </build>
- ...
- </project>
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.3</version>
</plugin>
</plugins>
</build>
...
</project>
maven-checkstyle-plugin的最新版本為2.5,其對應的CheckStyle核心版本為5.0;maven-checkstyle-plugin 2.3對應的CheckStyle核心版本為4.4。查看插件的pom文件,可看到如下內容,其中的版本號就為對應的CheckStyle的版本號。
- <dependency>
- <groupId>checkstyle</groupId>
- <artifactId>checkstyle</artifactId>
- <version>4.4</version>
- </dependency>
<dependency>
<groupId>checkstyle</groupId>
<artifactId>checkstyle</artifactId>
<version>4.4</version>
</dependency>
接下來,將自定義的規則配置文件拷貝到top級目錄,在reporting部分的CheckStyle插件配置中引用配置。
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <configLocation>my_checks.xml</configLocation>
- </configuration>
- </plugin>
- </plugins>
- </reporting>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>my_checks.xml</configLocation>
</configuration>
</plugin>
</plugins>
</reporting>
也可以將配置文件放在子文件夾下,配置中帶上相對路徑即可。
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <configLocation>build-tools/src/main/resources/xx/my_checks.xml</configLocation>
- </configuration>
- </plugin>
- </plugins>
- </reporting>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>build-tools/src/main/resources/xx/my_checks.xml</configLocation>
</configuration>
</plugin>
</plugins>
</reporting>
如果使用插件自帶的規則文件,可以作如下配置。maven-checkstyle-plugin插件自帶的規則有sun_checks.xml、maven_checks.xml等,可查看插件包。
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <configLocation>config/maven_checks.xml</configLocation>
- </configuration>
- <version>2.3</version>
- </plugin>
- </plugins>
- </reporting>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>config/maven_checks.xml</configLocation>
</configuration>
<version>2.3</version>
</plugin>
</plugins>
</reporting>
在reporting部分增加jxr插件,生成代碼報告,這樣在CheckStyle報告 中點擊問題對應的鏈接就可以直接看到出錯的代碼。
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <configLocation>my_checks.xml</configLocation>
- </configuration>
- <version>2.3</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jxr-plugin</artifactId>
- </plugin>
- </plugins>
- </reporting>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>my_checks.xml</configLocation>
</configuration>
<version>2.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
</plugin>
</plugins>
</reporting>
在build和reporting部分增加javadoc插件,如果pom文件中已經配置,則只需作相應修改。charset、encoding、docencoding配置用于解決生成的javadoc文件中文亂碼問題;aggregate配置為true則javadoc報告會集中顯示所有子模塊的javadoc。
- <reporting>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.4</version>
- <configuration>
- <aggregate>true</aggregate>
- <charset>UTF-8</charset>
- <encoding>UTF-8</encoding>
- <docencoding>UTF-8</docencoding>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <configLocation>my_checks.xml</configLocation>
- </configuration>
- <version>2.3</version>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jxr-plugin</artifactId>
- </plugin>
- </plugins>
- </reporting>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.4</version>
<configuration>
<aggregate>true</aggregate>
<charset>UTF-8</charset>
<encoding>UTF-8</encoding>
<docencoding>UTF-8</docencoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>my_checks.xml</configLocation>
</configuration>
<version>2.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
</plugin>
</plugins>
</reporting>
在maven插件中使用 install命令將pom文件中配置的插件下載安裝到本地,然后使用checkstyle:checkstyle命令進行檢查并生成報告,運行完畢,各項目目錄下會生成target目錄,target\site\checkstyle.html即為該項目的問題報告。
需要注意的是checkstyle:checkstyle僅生成CheckStyle相關報告,因此不能從報告中直接鏈接到錯誤代碼;需要同時生成jxr源代碼,使用site。
如果運行checkstyle:checkstyle或site過程中出現如下錯誤,則應該修改CheckStyle規 則配置文件,去除其中的中文字符。
- “[ERROR] BUILD ERROR
- [INFO] ------------------------------------------------------------------------
- [INFO] An error has occurred in Checkstyle report generation.
-
- Embedded error: Failed during checkstyle configuration
- Invalid byte 1 of 1-byte UTF-8 sequence.
- ”
“[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] An error has occurred in Checkstyle report generation.
Embedded error: Failed during checkstyle configuration
Invalid byte 1 of 1-byte UTF-8 sequence.
”
最佳實踐
自定義的checkstyle配置文件
以下代碼是自定義的checkstyle配置文件內容,相關說明都已經用注釋形式寫在文件中。代碼如下:
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<module name="Checker">
<!--
重復代碼的檢查,超過8行就認為重復,UTF-8格式 本檢查一定要放在"TreeWalker"節點前,否則在
Checkclipse中會無法使用。(在ant下可以)
-->
<module name="StrictDuplicateCode">
<property name="min" value="8" />
<property name="charset" value="UTF-8" />
</module>
<module name="TreeWalker">
<!-- javadoc的檢查 -->
<!-- 檢查所有的interface和class -->
<module name="JavadocType" />
<!-- 命名方面的檢查,它們都使用了Sun官方定的規則。 -->
<!-- 局部的final變量,包括catch中的參數的檢查 -->
<module name="LocalFinalVariableName" />
<!-- 局部的非final型的變量,包括catch中的參數的檢查 -->
<module name="LocalVariableName" />
<!-- 包名的檢查(只允許小寫字母) -->
<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$" />
</module>
<!-- 僅僅是static型的變量(不包括static final型)的檢查 -->
<module name="StaticVariableName" />
<!-- 類型(Class或Interface)名的檢查 -->
<module name="TypeName" />
<!-- 非static型變量的檢查 -->
<module name="MemberName" />
<!-- 方法名的檢查 -->
<module name="MethodName" />
<!-- 方法的參數名 -->
<module name="ParameterName " />
<!-- 常量名的檢查 -->
<module name="ConstantName" />
<!-- import方面的檢查 -->
<!-- import中避免星號"*" -->
<module name="AvoidStarImport" />
<!--
沒用的import檢查,比如:1.沒有被用到2.重復的3.import java.lang的4.import
與該類在同一個package的
-->
<module name="UnusedImports" />
<!-- 長度方面的檢查 -->
<!-- 文件長度不超過1500行 -->
<module name="FileLength">
<property name="max" value="1500" />
</module>
<!-- 每行不超過120個字-->
<module name="LineLength">
<property name="max" value="120" />
</module>
<!-- 方法不超過30行 -->
<module name="MethodLength">
<property name="tokens" value="METHOD_DEF" />
<property name="max" value="30" />
</module>
<!-- 方法的參數個數不超過3個。 并且不對構造方法進行檢查-->
<module name="ParameterNumber">
<property name="max" value="3" />
<property name="tokens" value="METHOD_DEF" />
</module>
<!-- 空格檢查 -->
<!-- 允許方法名后緊跟左邊圓括號"(" -->
<module name="MethodParamPad" />
<!-- 在類型轉換時,不允許左圓括號右邊有空格,也不允許與右圓括號左邊有空格 -->
<module name="TypecastParenPad" />
<!-- 不允許使用"tab"鍵 -->
<module name="TabCharacter" />
<!-- 關鍵字 -->
<!--
每個關鍵字都有正確的出現順序。比如 public static final XXX 是對一個常量的聲明。如果使用 static
public final 就是錯誤的
-->
<module name="ModifierOrder" />
<!-- 多余的關鍵字 -->
<module name="RedundantModifier" />
<!-- 對區域的檢查 -->
<!-- 不能出現空白區域 -->
<module name="EmptyBlock" />
<!-- 所有區域都要使用大括號。 -->
<module name="NeedBraces" />
<!-- 多余的括號 -->
<module name="AvoidNestedBlocks">
<property name="allowInSwitchCase" value="true" />
</module>
<!-- 編碼方面的檢查 -->
<!-- 不許出現空語句 -->
<module name="EmptyStatement" />
<!-- 每個類都實現了equals()和hashCode() -->
<module name="EqualsHashCode" />
<!-- 不許使用switch,"a++"這樣可讀性很差的代碼 -->
<module name="IllegalToken" />
<!-- 不許內部賦值 -->
<module name="InnerAssignment" />
<!-- 絕對不能容忍魔法數 -->
<module name="MagicNumber">
<property name="tokens" value="NUM_DOUBLE, NUM_INT" />
</module>
<!-- 循環控制變量不能被修改 -->
<module name="ModifiedControlVariable" />
<!-- 多余的throw -->
<module name="RedundantThrows" />
<!-- 不許使用未被簡化的條件表達式 -->
<module name="SimplifyBooleanExpression" />
<!-- 不許使用未被簡化的布爾返回值 -->
<module name="SimplifyBooleanReturn" />
<!-- String的比較不能用!= 和 == -->
<module name="StringLiteralEquality" />
<!-- if最多嵌套3層 -->
<module name="NestedIfDepth">
<property name="max" value="3" />
</module>
<!-- try最多被嵌套2層 -->
<module name="NestedTryDepth">
<property name="max" value="2" />
</module>
<!-- clone方法必須調用了super.clone() -->
<module name="SuperClone" />
<!-- finalize 必須調用了super.finalize() -->
<module name="SuperFinalize" />
<!-- 不能catch java.lang.Exception -->
<module name="IllegalCatch">
<property name="illegalClassNames" value="java.lang.Exception" />
</module>
<!-- 確保一個類有package聲明 -->
<module name="PackageDeclaration" />
<!-- 一個方法中最多有3個return -->
<module name="ReturnCount">
<property name="max" value="3" />
<property name="format" value="^$" />
</module>
<!--
根據 Sun 編碼規范, class 或 interface 中的順序如下: 1.class 聲明。首先是 public,
然后是protected , 然后是 package level (不包括access modifier ) 最后是private .
(多個class放在一個java文件中的情況) 2.變量聲明。 首先是 public, 然后是protected然后是 package
level (不包括access modifier ) 最后是private . (多個class放在一個java文件中的情況)
3.構造函數 4.方法
-->
<module name="DeclarationOrder" />
<!-- 不許對方法的參數賦值 -->
<module name="ParameterAssignment" />
<!-- 確保某個class 在被使用時都已經被初始化成默認值(對象是null,數字和字符是0,boolean 變量是false.) -->
<module name="ExplicitInitialization" />
<!-- 不許有同樣內容的String -->
<module name="MultipleStringLiterals" />
<!-- 同一行不能有多個聲明 -->
<module name="MultipleVariableDeclarations" />
<!-- 不必要的圓括號 -->
<module name="UnnecessaryParentheses" />
<!-- 各種量度 -->
<!-- 布爾表達式的復雜度,不超過3 -->
<module name="BooleanExpressionComplexity" />
<!-- 類數據的抽象耦合,不超過7 -->
<module name="ClassDataAbstractionCoupling" />
<!-- 類的分散復雜度,不超過20 -->
<module name="ClassFanOutComplexity" />
<!-- 函數的分支復雜度,不超過10 -->
<module name="CyclomaticComplexity" />
<!-- NPath復雜度,不超過200 -->
<module name="NPathComplexity" />
<!-- 雜項 -->
<!-- 禁止使用System.out.println -->
<module name="GenericIllegalRegexp">
<property name="format" value="System\.out\.println" />
<property name="ignoreComments" value="true" />
</module>
<!-- 不許使用main方法 -->
<module name="UncommentedMain" />
<!-- 檢查并確保所有的常量中的L都是大寫的。因為小寫的字母l跟數字1太象了 -->
<module name="UpperEll" />
<!-- 檢查數組類型的定義是String[] args,而不是String args[] -->
<module name="ArrayTypeStyle" />
<!--
檢查java代碼的縮進 默認配置:基本縮進 4個空格,新行的大括號:0。新行的case 4個空格。
-->
<module name="Indentation" />
</module>
<!-- 檢查翻譯文件 -->
<module name="Translation" />
</module>
CheckStyle應用的最佳實踐
采用CheckStyle以后,編碼規范的檢查就變得及其簡單,可以作為一項切實可行的實踐加以執行。
一般情況下,在項目小組中引入CheckStyle可以按照下面的步驟進行:
1. 強調Code Review與Code Conventions的重要作用;
2. 介紹CheckStyle;
3. 初步應用CheckStyle:參照CheckStyle附帶的配置文件,酌情加以剪裁,在項目的Maven配置文件中,添加CheckStyle任務,可以 單獨執行;
4. 修改、定型CheckStyle的配置文件:按照基本配置文件執行一段時間(2~3周),聽取開發人員的反饋意見,修改配置信息;
5. 作為開發過程的日常實踐,強制執行CheckStyle:穩定CheckStyle的配置信息,同時將CheckStyle任務作為Build的依賴任務 或者配置SCM(目前,CheckStyle可以與SVN有效集成),使得代碼在加入系統 之前必須通過檢查。
同時需要指出的是,CheckStyle的有效執行需要依賴的條件:
•IDE Format Code的強大功能:由于CheckStyle本身并沒有提供很強大的Code Format等功能,因此,需要借助IDE的幫助,從而使得在發生錯誤的時候,可以很容易的進行修復。
IDE格式配置使用介紹
在eclipse中的window?preferences?java?code style中可以導入自定義的java編碼風格文件。如下圖:
點擊“Clean Up”,在右側可以看見一個Import按鈕,導入自定義的cleanup文件,點擊“OK”即可。左側的“Formatter”也是如法炮制。具體自定義的checkstyle,cleanup,formatter文件可參考壓縮包文件中的公司代碼規范文件夾。