Checkstyle配置文件及常见输出结果

1    Checkstyle配置文件

1.1    默认配置文件

Checkstyle检查是按照对应的配置文件进行检查的。解压Checkstyle安装包,解压...\plugins\net.sf.eclipsecs.core_6.11.1.201510102004.jar包,可以看到三个默认配置文件。

   

三个配置文件结构差不错,以google_checks.xml为例子。google_checks.xml是由多个module节点构成,因此可以发现:Checkstyle配置是通过指定modules来应用到java文件的。modules是树状结构,以一个名为Checker的module作为root节点,一般的checker都会包括TreeWalker子module。在xml配置文件中通过module的name属性来区分module,module的Properties可以控制如何去执行这个module,每个property都有一个默认值,所有的check都有一个severity属性,用它来指定check的level。TreeWalker为每个java文件创建一个语法树,在节点之间调用submodules的Checks

1.2    配置文件中的一些具体用法

1.2.1 JavadocComments

JavadocPackage

检查每个java package中是否有java注释文件,默认是允许一个package-info.java,也可以通过allowLegacy属性配置允许package.html。

JavadocType

检查类和接口的javadoc。默认不检查author 和version tags。

JavadocMethod

检查方法和构造函数的javadoc。默认不检查未使用的异常抛出。

JavadocVariable

检查变量的javadoc。

JavadocStyle

检查javadoc的格式。比如:javadoc的第一行是否以句号结束,javadoc除了tags外是否有description,检查javadoc中的html格式。

WriteTag

输出javadoc中的tag。

1.2.2 NamingConventions

AbstractClassName

检查抽象类名。

ClassTypeParameterName

检查类的Parameter名。

ConstantName

检查常量名。

LocalFinalVariableName

检查局部的final类型变量名,包括catch的参数。

LocalVarableName

检查局部的非final类型的变量名,包括catch的参数。

MemberName

检查非静态变量。

MethodName

检查方法名。

MethodTypeParameterName

检查方法的参数名。

PackageName

检查包名。

ParameterName

检查参数名。

StaticVariableName

检查静态的,非final类型的变量名。

TypeName

检查类名和接口名。

1.2.3 Imports

AvoidStarImport

检查是否有使用*进行import。

AvoidStaticImport

检查是否有静态import。比如是否导入了java.lang包中的内容。

IllegalImport

检查是否import了违法的包。默认拒绝import所有sun.*包。

RedundanImport

检查是否有重复的import。

UnusedImports

检查是否有未使用的import。

ImportOrder

检查import的分组和顺序。

ImportControl

控制可import的包。在一个较大的project可限制使用过多的第三方包,通过一个依照http://www.puppycrawl.com/dtds/import_control_1_0.dtd的xml文件来指定。

1.2.4 SizeViolations

ExecutableStatementCount

限制可执行代码片段的长度。默认为30。

FileLength

检查java文件的长度。默认为2000。

LineLength

检查代码行的长度。默认为80。

MethodLength

检查方法和构造函数的长度。默认为150。

AnonInnerLength

检查匿名内部类的长度。默认为20。

ParameterNumber

检查方法和构造函数的参数个数。默认为7。

1.2.5 Whitespace

GenericWhitespace

检查<和>周围的空白。

EmptyForInitializerPad

检查空的初始化位置的空白。比如for循环中的初始化。

EmptyForIteratorPad

检查空的迭代位置的空白。

MethodParamPad

检查方法签名之前的空白。

NoWhitespaceAfter

检查分隔符后的空白。

NoWhitespaceBefore

检查分隔符前的空白。

OperatorWrap

检查操作符的空白规则。

ParenPad

检查圆括号的空白规则。

TypecaseParenPad

检查强制转型的圆括号的空白规则。

TabCharacter

检查是否有Tab字符(’"t’)。

WhitespaceAfter

检查分隔符是否在空白之后。

WhitespaceAround

检查分隔符周围是否有空白。

1.2.6 ModifierOrder

ModifierOrder

检查修饰符的顺序是否遵照java语言规范。

RedundantModifier

检查接口和annotation中是否有重复的修饰符。

1.2.7 BlockChecks

EmptyBlock

检查空的代码块。

LeftCurly

检查’{’和左边的代码块是否在同一行。

NeedBraces

检查是否需要大括号。主要是在if,else时的情况。

RightCurly

检查’}’。

AvoidNestedBlocks

检查不需要的嵌套’{}’。

1.2.8 Coding

ArrayTrailingComma

检查数组初始化是否以逗号结束。

AvoidInlineConditionals

检查inline的条件操作。

CovariantEquals

检查类是否覆盖了equals(java.lang.Object)。

DoubleCheckedLocking

检查DCL的问题。

EmptyStatement

检查空的代码段。

EqualsAvoidNull

检查一个可能为null的字符串是否在equals()比较的左边。

EqualsHashCode

检查类是否覆盖了equals()和hashCode()。

FinalLocalVariable

检查未改变过的局部变量是否声明为final。

HiddenField

检查局部变量或参数是否隐藏了类中的变量。

IllegalInstantiation

检查是否使用工厂方法实例化。

IllegalToken

检查非法的分隔符。

IllegalTokenText

检查非法的分隔符的下个字符。

InnerAssignment

检查子表达式中是否有赋值操作。

MagicNumber

检查是否有“magic numbers”。

MissingSwitchDefault

检查switch语句是否有default的clause。

ModifiedControlVariable

检查循环控制的变量是否在代码块中被修改。

RedundantThrows

检查是否有被重复抛出的异常。

SimplifyBooleanExpression

检查是否有过度复杂的布尔表达式。

SimplifyBooleanReturn

检查是否有过于复杂的布尔返回代码段。

StringLiteralEquality

检查字符串是否有用= =或!=进行操作。

NestedIfDepth

检查嵌套的层次深度。

NestedTryDepth

检查try的层次深度。

NoClone

检查是否覆盖了clone()。

NoFinalizer

检查是否有定义finalize()。

SuperClone

检查覆盖的clone()是否有调用super.clone()。

SuperFinalize

检查覆盖的finalize()是否有调用super.finalize()。

IllegalCatch

检查是否catch了不能接受的错误。

IllegalThrows

检查是否抛出了未声明的异常。

PackageDeclaration

检查类中是否有声明package。

JUnitTestCase

确保setUp(), tearDown()方法签名的正确性。

ReturnCount

限制return代码段的数量。

IllegalType

检查未使用过的类。

DeclarationOrder

检查类和接口中的声明顺序。

ParameterAssignment

检查不允许的参数赋值。

ExplicitInitialization

检查类和对象成员是否初始化为默认值。

DefaultComesLast

检查default的clause是否在switch代码段的最后。

MissingCtor

检查类依赖。

FallThrough

检查switch代码的case中是否缺少break,return,throw和continue。

MultipleStringLiterals

检查一个文件中是否有多次出现的字符串。

MultipleVariableDeclarations

检查代码段和代码行中是否有多次变量声明。

RequireThis

检查代码中是否有“this.”。

UnnecessaryParentheses

检查是否有使用不需要的圆括号。

ClassDesign

VisibilityModifier

检查类成员的可见度。

FinalClass

检查只有private构造函数的类是否声明为final。

InterfaceIsType

检查接口是否仅定义类型。

HideUtilityClassConstructor

检查工具类是否有putblic的构造器。

DesignForExension

检查类是否为扩展设计。

MutableException

确保异常是不可变的。

ThrowsCount

限制抛出异常的数量。

1.2.9 DuplicateCode

StrictDuplicateCode

严格检查重复代码。

1.2.10   Miscellaneous

GenericIllegalRegexp

正则表达式的模式检查。

NewlineAtEndOfFile

检查文件是否以一个空行结束。

TodoComment

检查TODO:注释。

Translation

检查property文件中是否有相同的key。

UncommentedMain

检查是否有未注释的main方法。

UpperEll

检查long型约束是否有大写的“L”。

ArrayTypeStyle

检查数组类型定义的样式。

FinalParameters

检查方法名、构造函数、catch块的参数是否是final的。

Indentation

检查代码中正确的缩进。

TrailingComment

确保是否要代码行注释。

RequiredRegexp

确保一个指定的正则表达式的规则已经存在代码中。

详细的检查项,可以参考Checkstyle的官网http://Checkstyle.sourceforge.net/

1.3    定制配置文件

个人使用Checkstyle默认检查项后的感受是,觉得规范过于严格,项目上可以根据默认配置文件进行项目定制,定制后,更新eclipse中的配置项 ,如下图。

备注:附件checkStyleFromHuaWei.xml为华为使用的配置文件,仅供参考。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<!-- Generated by RHY @will_awoke -->
<module name="Checker">
<property name="charset" value="UTF-8"/>   
<property name="severity" value="warning"/>
<!-- Checks for Size Violations.  --> 
<!-- 检查文件的长度(行) default max=2000 --> 
<module name="FileLength">         
     <property name="max" value="2500"/>        
  </module>  
  
  <!-- Checks that property files contain the same keys. --> 
  <!-- 检查**.properties配置文件 是否有相同的key
  <module name="Translation">         
  </module>   
  --> 

  <module name="TreeWalker">
        <!-- Checks for imports    -->               
    <!-- 必须导入类的完整路径,即不能使用*导入所需的类 -->  
    <module name="AvoidStarImport"/>  
    
    <!-- 检查是否从非法的包中导入了类 illegalPkgs: 定义非法的包名称-->  
    <module name="IllegalImport"/> <!-- defaults to sun.* packages -->  
    
    <!-- 检查是否导入了不必显示导入的类-->  
    <module name="RedundantImport"/>  
    
    <!-- 检查是否导入的包没有使用-->  
    <module name="UnusedImports"/>
    
    <!-- Checks for whitespace           
    <module name="EmptyForIteratorPad"/>
    <module name="MethodParamPad"/>
    <module name="NoWhitespaceAfter"/>
    <module name="NoWhitespaceBefore"/>
    <module name="OperatorWrap"/>
    <module name="ParenPad"/>
    <module name="TypecastParenPad"/>
    <module name="WhitespaceAfter"/>
    <module name="WhitespaceAround"/>
    -->
    
    <!-- 检查类和接口的javadoc 默认不检查author 和version tags       
      authorFormat: 检查author标签的格式
versionFormat: 检查version标签的格式
scope: 可以检查的类的范围,例如:public只能检查public修饰的类,private可以检查所有的类
excludeScope: 不能检查的类的范围,例如:public,public的类将不被检查,但访问权限小于public的类仍然会检查,其他的权限以此类推
tokens: 该属性适用的类型,例如:CLASS_DEF,INTERFACE_DEF -->
    <module name="JavadocType">  
    <property name="authorFormat" value="\S"/>  
      <property name="scope" value="protected"/>        
      <property name="tokens" value="CLASS_DEF,INTERFACE_DEF"/>  
    </module>
    
    <!-- 检查方法的javadoc的注释
scope: 可以检查的方法的范围,例如:public只能检查public修饰的方法,private可以检查所有的方法
allowMissingParamTags: 是否忽略对参数注释的检查
allowMissingThrowsTags: 是否忽略对throws注释的检查
allowMissingReturnTag: 是否忽略对return注释的检查 -->
    <module name="JavadocMethod">  
    <property name="scope" value="private"/>  
      <property name="allowMissingParamTags" value="false"/>  
      <property name="allowMissingThrowsTags" value="false"/>  
      <property name="allowMissingReturnTag" value="false"/>  
      <property name="tokens" value="METHOD_DEF"/>  
      <property name="allowUndeclaredRTE" value="true"/>  
      <property name="allowThrowsTagsForSubclasses" value="true"/>  
      <!--允许get set 方法没有注释-->
     <property name="allowMissingPropertyJavadoc" value="true"/>
    </module>  
        
    <!-- 检查类变量的注释
scope: 检查变量的范围,例如:public只能检查public修饰的变量,private可以检查所有的变量 -->    
    <module name="JavadocVariable">  
      <property name="scope" value="private"/>  
    </module>  
        
    <!--option: 定义左大括号'{'显示位置,eol在同一行显示,nl在下一行显示  
      maxLineLength: 大括号'{'所在行行最多容纳的字符数  
      tokens: 该属性适用的类型,例:CLASS_DEF,INTERFACE_DEF,METHOD_DEF,CTOR_DEF -->  
    <module name="LeftCurly"> 
    <property name="option" value="nl"/>
    </module>
     
    <!-- NeedBraces 检查是否应该使用括号的地方没有加括号  
      tokens: 定义检查的类型 -->  
    <module name="NeedBraces"/>  
    
    <!-- Checks the placement of right curly braces ('}') for  else, try, and catch tokens. The policy to verify is specified using property  option.   
      option: 右大括号是否单独一行显示  
      tokens: 定义检查的类型  -->  
    <module name="RightCurly">    
    <property name="option" value="alone"/>
    </module>
        
    <!-- 检查在重写了equals方法后是否重写了hashCode方法 --> 
    <module name="EqualsHashCode"/>
        
    <!--  Checks for illegal instantiations where a factory method is preferred.  
      Rationale: Depending on the project, for some classes it might be preferable to create instances through factory methods rather than calling the constructor.  
      A simple example is the java.lang.Boolean class. In order to save memory and CPU cycles, it is preferable to use the predefined constants TRUE and FALSE. Constructor invocations should be replaced by calls to Boolean.valueOf().  
      Some extremely performance sensitive projects may require the use of factory methods for other classes as well, to enforce the usage of number caches or object pools. -->  
    <module name="IllegalInstantiation">  
    <property name="classes" value="java.lang.Boolean"/>  
    </module>
    
    <!-- Checks for Naming Conventions.   命名规范   -->
    <!-- local, final variables, including catch parameters -->
    <module name="LocalFinalVariableName"/>
    
    <!-- local, non-final variables, including catch parameters--> 
    <module name="LocalVariableName"/>
    
    <!-- static, non-final fields -->
    <module name="StaticVariableName">
    <property name="format" value="(^[A-Z0-9_]{0,19}$)"/>    
    </module>  
    
    <!-- packages -->
    <module name="PackageName" >
    <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
    </module> 
     
    <!-- classes and interfaces -->
    <module name="TypeName">  
    <property name="format" value="(^[A-Z][a-zA-Z0-9]{0,19}$)"/>
    </module>
    
    <!-- methods -->  
    <module name="MethodName">          
      <property name="format" value="(^[a-z][a-zA-Z0-9]{0,19}$)"/>         
    </module> 
    
    <!-- non-static fields -->
    <module name="MemberName">  
    <property name="format" value="(^[a-z][a-z0-9][a-zA-Z0-9]{0,19}$)"/>         
    </module>
    
    <!-- parameters -->
    <module name="ParameterName">
    <property name="format" value="(^[a-z][a-zA-Z0-9_]{0,19}$)"/>         
    </module>
    
    <!-- constants (static,  final fields) -->
    <module name="ConstantName"> 
    <property name="format" value="(^[A-Z0-9_]{0,19}$)"/>      
    </module>
    
    <!-- 代码缩进   -->
    <module name="Indentation">        
    </module>
    
    <!-- Checks for redundant exceptions declared in throws clause such as duplicates, unchecked exceptions or subclasses of another declared exception. 
      检查是否抛出了多余的异常  
    <module name="RedundantThrows">
    <property name="logLoadErrors" value="true"/>
    <property name="suppressLoadErrors" value="true"/> 
    </module>
    --> 
    
     <!--  Checks for overly complicated boolean expressions. Currently finds code like  if (b == true), b || true, !false, etc.   
       检查boolean值是否冗余的地方  
       Rationale: Complex boolean logic makes code hard to understand and maintain. -->  
    <module name="SimplifyBooleanExpression"/>
    
    <!--  Checks for overly complicated boolean return statements. For example the following code  
       检查是否存在过度复杂的boolean返回值  
       if (valid())  
          return false;  
       else  
          return true;  
       could be written as  
          return !valid();  
       The Idea for this Check has been shamelessly stolen from the equivalent PMD rule. -->  
    <module name="SimplifyBooleanReturn"/>  
    
    <!-- Checks that a class which has only private constructors is declared as final.只有私有构造器的类必须声明为final-->  
    <module name="FinalClass"/>
    
     <!--  Make sure that utility classes (classes that contain only static methods or fields in their API) do not have a public constructor.  
       确保Utils类(只提供static方法和属性的类)没有public构造器。  
       Rationale: Instantiating utility classes does not make sense. Hence the constructors should either be private or (if you want to allow subclassing) protected. A common mistake is forgetting to hide the default constructor.  
       If you make the constructor protected you may want to consider the following constructor implementation technique to disallow instantiating subclasses:  
       public class StringUtils // not final to allow subclassing  
       {  
           protected StringUtils() {  
               throw new UnsupportedOperationException(); // prevents calls from subclass  
           }  
           public static int count(char c, String s) {  
               // ...  
           }  
       } 
    <module name="HideUtilityClassConstructor"/> 
    --> 
    
    <!--  Checks visibility of class members. Only static final members may be public; other class members must be private unless property protectedAllowed or packageAllowed is set.  
      检查class成员属性可见性。只有static final 修饰的成员是可以public的。其他的成员属性必需是private的,除非属性protectedAllowed或者packageAllowed设置了true.  
       Public members are not flagged if the name matches the public member regular expression (contains "^serialVersionUID$" by default). Note: Checkstyle 2 used to include "^f[A-Z][a-zA-Z0-9]*$" in the default pattern to allow CMP for EJB 1.1 with the default settings. With EJB 2.0 it is not longer necessary to have public access for persistent fields, hence the default has been changed.  
       Rationale: Enforce encapsulation. 强制封装 -->  
    <module name="VisibilityModifier"/> 
    
    <!-- 每一行只能定义一个变量 -->
    <module name="MultipleVariableDeclarations">       
    </module>
    
     <!-- Checks the style of array type definitions. Some like Java-style: public static void main(String[] args) and some like C-style: public static void main(String args[])   
       检查再定义数组时,采用java风格还是c风格,例如:int[] num是java风格,int num[]是c风格。默认是java风格-->  
    <module name="ArrayTypeStyle"> 
    </module>
    
    <!-- Checks that there are no "magic numbers", where a magic number is a numeric literal that is not defined as a constant. By default, -1, 0, 1, and 2 are not considered to be magic numbers. 
    <module name="MagicNumber">   
    </module>
    -->  
    
    <!-- A check for TODO: comments. Actually it is a generic regular expression matcher on Java comments. To check for other patterns in Java comments, set property format.   
       检查是否存在TODO(待处理) TODO是javaIDE自动生成的。一般代码写完后要去掉。  
     -->  
    <module name="TodoComment"/>  
    
    <!--  Checks that long constants are defined with an upper ell. That is ' L' and not 'l'. This is in accordance to the Java Language Specification,  Section 3.10.1.  
      检查是否在long类型是否定义了大写的L.字母小写l和数字1(一)很相似。  
      looks a lot like 1. -->  
    <module name="UpperEll"/>
    
    <!--  Checks that switch statement has "default" clause. 检查switch语句是否有‘default’从句  
       Rationale: It's usually a good idea to introduce a default case in every switch statement. 
       Even if the developer is sure that all currently possible cases are covered, this should be expressed in the default branch,
        e.g. by using an assertion. This way the code is protected aginst later changes, e.g. introduction of new types in an enumeration type. --> 
    <module name="MissingSwitchDefault"/> 
    
    <!--检查switch中case后是否加入了跳出语句,例如:return、break、throw、continue -->
    <module name="FallThrough"/>  
    
    <!-- Checks the number of parameters of a method or constructor. max default 7个. -->    
    <module name="ParameterNumber">      
      <property name="max" value="5"/>              
    </module>
    
    <!-- 每行字符数 -->    
    <module name="LineLength">  
      <property name="max" value="200"/>       
    </module>  
    
    <!-- Checks for long methods and constructors. max default 150行. max=300 设置长度300 --> 
    <module name="MethodLength">  
      <property name="max" value="300"/>                 
    </module>        
    
    <!-- ModifierOrder 检查修饰符的顺序,默认是 public,protected,private,abstract,static,final,transient,volatile,synchronized,native -->  
    <module name="ModifierOrder">          
    </module>      
    
    <!-- 检查是否有多余的修饰符,例如:接口中的方法不必使用public、abstract修饰  -->
    <module name="RedundantModifier">       
    </module>
    
    <!--- 字符串比较必须使用 equals() -->   
    <module name="StringLiteralEquality">          
    </module> 
    
    <!-- if-else嵌套语句个数 最多4层 -->
    <module name="NestedIfDepth">        
      <property name="max" value="3"/>         
    </module>  
    
    <!-- try-catch 嵌套语句个数 最多2层 -->
    <module name="NestedTryDepth">  
      <property name="max" value="2"/>         
    </module>  
        
    <!-- 返回个数 -->   
    <module name="ReturnCount">        
      <property name="max" value="5"/>  
      <property name="format" value="^$"/>          
    </module>                  
    </module>
  </module>



2    Checkstyle常见输出结果

Checkstyle常见错误和警告提示见下表所示:

错误提示

错误说明

missing a javadoc comment

缺少类注释

Line longer than X characters

行长度超过X个字符(包括空格)

Return count is X(max allowed 3)

一个方法内的返回数量是X(最大值只能为3)

Nested if-else depth is X(max allowed is 3)

最大的if-else嵌套层数为X(最大只能为3)

Array brackets at illegal position

数组的方括号“[]”的位置不正确(检查数组类型的定义是String[] args,而不是String args[])

Line matchs the illegal pattern 'System\.out\.println'

本行包含System.out.println语句

ctor def modifier at indentation level 8 not at corrent indentation 4

缩进不正确,一般是因为没有在Eclipse中使用4个空格代替tab键引起。

'static' modifier out of order with the JLS suggestions

static修饰符没有按照JLS的建议来排序(eg.写成public final static...应该改成public static final)

Name 'X' must match pattern '^[A-Z][A-Z0-9][_A-Z0-9+]$'(正则表达式)

名称不符合正则表达式'^[A-Z][A-Z0-9][_A-Z0-9+]$'(即为大写字母,数字、下划线等)。

一般在静态变量没有大写时提示,包名不是全部消息时提示,类名不是大写开头时提示,方法名不是小写开头时提示

Variable access definition in wrong order

变量定义顺序不正确(例如在类成员变量定义时,将private类型的变量定义在public类型的变量之前)

Static variable definition in wrong order

静态变量定义顺序不正确(例如在构造函数之后定义静态变量)

Instance variable definition in wrong order

成员变量定义顺序不正确(例如在构造函数之后定义成员变量)

X is a magic number

X是一个魔术数字(非0、1、2的数字)

if construct must use '{}'

if结构必须使用'{}'

Got an exception - Unexpected character 0xfffd in identifier

因为没有设置Checkstyle配置文件的charset为UTF-8,而类文件使用UTF-8编码,并且含有中文

“{” should be on the previous line

“{” 应该位于前一行

Methods is missing a javadoc comment

方法前面缺少javadoc注释

Expected @throws tag for “Exception”

在注释中希望有@throws的说明

“.” Is preceeded with whitespace

“.” 前面不能有空格

“.” Is followed by whitespace

“.” 后面不能有空格

“=” is not preceeded with whitespace“=”

前面缺少空格

“=” is not followed with whitespace

“=” 后面缺少空格

“}” should be on the same line

“}” 应该与下条语句位于同一行

Unused @param tag for “unused”

没有参数“unused”,不需注释

Variable “X” missing javadoc

变量“CA”缺少javadoc注释

Line contains a tab character

行含有”tab” 字符

Redundant “Public” modifier

冗余的“public” modifier

final modifier out of order with the JSL suggestion

final修饰符的顺序错误

Avoid using the “.*” form of import

Import格式避免使用“.*”

Redundant import from the same package

从同一个包中Import内容

Unused import-X Import

import的X类没有被使用

Duplicate import to line X

重复Import同一个内容

Import from illegal package

从非法包中 Import内容

“while” construct must use “{}”

“while” 语句缺少“{}”

Variable “X” must be private and have accessor method

变量“X”应该是private的,并且有调用它的方法

Variable “X” must match pattern“^[a-z][a-zA-Z0-9]*$”

变量“X”不符合命名规则“^[a-z][a-zA-Z0-9]*$”

“(” is followed by whitespace

“(” 后面不能有空格

“)” is proceeded by whitespace

“)” 前面不能有空格

猜你喜欢

转载自blog.csdn.net/emily201314/article/details/50131395
今日推荐