Checkstyle安装使用规范
Checkstyle
是SourceForge下的一个项目,提供了一个帮助JAVA开发人员遵守某些编码规范的工具。它能够自动化代码规范检查过程,从而使得开发人员从这项重要,但是枯燥的任务中解脱出来。
CheckStyle检验的主要内容
- Javadoc注释
- 命名约定
- 标题
- Import语句
- 体积大小
- 空白
- 修饰符
- 块
- 代码问题
- 类设计
- 混合检查(包括一些有用的比如非必须的System.out和printstackTrace)
AS安装Checkstyle工具使用操作
下载CheckStyle-IDEA-5.21.0.zip (下载的有直接导入即可)
步骤








Checkstyle.xml 书写
书写模板
`<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<!--
If you set the basedir property below, then all reported file
names will be relative to the specified directory. See
http://checkstyle.sourceforge.net/5.x/config.html#Checker
<property name="basedir" value="${basedir}"/>
-->
<!-- 检查每个包中是否有java注释文件,默认有package-info.java -->
<!-- <module name="JavadocPackage"/> -->
<!-- 检查文件是否以一个空行结束 -->
<module name="NewlineAtEndOfFile"/>
<!-- 检查property文件中是否有相同的key -->
<module name="Translation"/>
<!-- 文件长度不超过1500行 -->
<module name="FileLength">
<property name="max" value="1500"/>
</module>
<!-- 检查文件中是否含有'\t' -->
<module name="FileTabCharacter"/>
<!-- Miscellaneous other checks. -->
<module name="RegexpSingleline">
<property name="format" value="\s+$"/>
<property name="minimum" value="0"/>
<property name="maximum" value="0"/>
<property name="message" value="Line has trailing spaces."/>
</module>
<!-- 每个java文件一个语法树 -->
<module name="TreeWalker">
<!-- 注释检查 -->
<!-- 检查方法和构造函数的javadoc -->
<module name="JavadocMethod">
<property name="tokens" value="METHOD_DEF" />
</module>
<!-- 检查类和接口的javadoc。默认不检查author和version tags -->
<module name="JavadocType"/>
<!-- 检查变量的javadoc -->
<module name="JavadocVariable"/>
<!-- 检查javadoc的格式 -->
<module name="JavadocStyle">
<property name="checkFirstSentence" value="false"/>
</module>
<!-- 检查TODO:注释 -->
<module name="TodoComment"/>
<!-- 命名检查 -->
<!-- 局部的final变量,包括catch中的参数的检查 -->
<module name="LocalFinalVariableName" />
<!-- 局部的非final型的变量,包括catch中的参数的检查 -->
<module name="LocalVariableName" />
<!-- 包名的检查(只允许小写字母),默认^[a-z]+(\.[a-zA-Z_][a-zA-Z_0-9_]*)*$ -->
<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$" />
<message key="name.invalidPattern" value="包名 ''{0}'' 要符合 ''{1}''格式."/>
</module>
<!-- 仅仅是static型的变量(不包括static final型)的检查 -->
<module name="StaticVariableName" />
<!-- Class或Interface名检查,默认^[A-Z][a-zA-Z0-9]*$-->
<module name="TypeName">
<property name="severity" value="warning"/>
<message key="name.invalidPattern" value="名称 ''{0}'' 要符合 ''{1}''格式."/>
</module>
<!-- 非static型变量的检查 -->
<module name="MemberName" />
<!-- 方法名的检查 -->
<module name="MethodName" />
<!-- 方法的参数名 -->
<module name="ParameterName " />
<!-- 常量名的检查(只允许大写),默认^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$ -->
<module name="ConstantName" />
<!-- 定义检查 -->
<!-- 检查数组类型定义的样式 -->
<module name="ArrayTypeStyle"/>
<!-- 检查方法名、构造函数、catch块的参数是否是final的 -->
<!-- <module name="FinalParameters"/> -->
<!-- 检查long型定义是否有大写的“L” -->
<module name="UpperEll"/>
<!-- Checks for Headers -->
<!-- See http://checkstyle.sf.net/config_header.html -->
<!-- <module name="Header"> -->
<!-- The follow property value demonstrates the ability -->
<!-- to have access to ANT properties. In this case it uses -->
<!-- the ${basedir} property to allow Checkstyle to be run -->
<!-- from any directory within a project. See property -->
<!-- expansion, -->
<!-- http://checkstyle.sf.net/config.html#properties -->
<!-- <property -->
<!-- name="headerFile" -->
<!-- value="${basedir}/java.header"/> -->
<!-- </module> -->
<!-- Following interprets the header file as regular expressions. -->
<!-- <module name="RegexpHeader"/> -->
<!-- import检查-->
<!-- 避免使用* -->
<module name="AvoidStarImport"/>
<!-- 检查是否从非法的包中导入了类 -->
<module name="IllegalImport"/>
<!-- 检查是否导入了多余的包 -->
<module name="RedundantImport"/>
<!-- 没用的import检查,比如:1.没有被用到2.重复的3.import java.lang的4.import 与该类在同一个package的 -->
<module name="UnusedImports" />
<!-- 长度检查 -->
<!-- 每行不超过150个字符 -->
<module name="LineLength">
<property name="max" value="150" />
</module>
<!-- 方法不超过150行 -->
<module name="MethodLength">
<property name="tokens" value="METHOD_DEF" />
<property name="max" value="150" />
</module>
<!-- 方法的参数个数不超过5个。 并且不对构造方法进行检查-->
<module name="ParameterNumber">
<property name="max" value="10" />
<property name="ignoreOverriddenMethods" value="true"/>
<property name="tokens" value="METHOD_DEF" />
</module>
<!-- 空格检查-->
<!-- 方法名后跟左圆括号"(" -->
<module name="MethodParamPad" />
<!-- 在类型转换时,不允许左圆括号右边有空格,也不允许与右圆括号左边有空格 -->
<module name="TypecastParenPad" />
<!-- Iterator -->
<!-- <module name="EmptyForIteratorPad"/> -->
<!-- 检查尖括号 -->
<!-- <module name="GenericWhitespace"/> -->
<!-- 检查在某个特定关键字之后应保留空格 -->
<module name="NoWhitespaceAfter"/>
<!-- 检查在某个特定关键字之前应保留空格 -->
<module name="NoWhitespaceBefore"/>
<!-- 操作符换行策略检查 -->
<module name="OperatorWrap"/>
<!-- 圆括号空白 -->
<module name="ParenPad"/>
<!-- 检查分隔符是否在空白之后 -->
<module name="WhitespaceAfter"/>
<!-- 检查分隔符周围是否有空白 -->
<module name="WhitespaceAround"/>
<!-- 修饰符检查 -->
<!-- 检查修饰符的顺序是否遵照java语言规范,默认public、protected、private、abstract、static、final、transient、volatile、synchronized、native、strictfp -->
<module name="ModifierOrder"/>
<!-- 检查接口和annotation中是否有多余修饰符,如接口方法不必使用public -->
<module name="RedundantModifier"/>
<!-- 代码块检查 -->
<!-- 检查是否有嵌套代码块 -->
<module name="AvoidNestedBlocks"/>
<!-- 检查是否有空代码块 -->
<module name="EmptyBlock"/>
<!-- 检查左大括号位置 -->
<module name="LeftCurly"/>
<!-- 检查代码块是否缺失{} -->
<module name="NeedBraces"/>
<!-- 检查右大括号位置 -->
<module name="RightCurly"/>
<!-- 代码检查 -->
<!-- 检查是否在同一行初始化 -->
<!-- <module name="AvoidInlineConditionals"/> -->
<!-- 检查空的代码段 -->
<module name="EmptyStatement"/>
<!-- 检查在重写了equals方法后是否重写了hashCode方法 -->
<module name="EqualsHashCode"/>
<!-- 检查局部变量或参数是否隐藏了类中的变量 -->
<module name="HiddenField">
<property name="tokens" value="VARIABLE_DEF"/>
</module>
<!-- 检查是否使用工厂方法实例化 -->
<module name="IllegalInstantiation"/>
<!-- 检查子表达式中是否有赋值操作 -->
<module name="InnerAssignment"/>
<!-- 检查是否有"魔术"数字 -->
<module name="MagicNumber">
<property name="ignoreNumbers" value="0, 1"/>
<property name="ignoreAnnotation" value="true"/>
</module>
<!-- 检查switch语句是否有default -->
<module name="MissingSwitchDefault"/>
<!-- 检查是否有过度复杂的布尔表达式 -->
<module name="SimplifyBooleanExpression"/>
<!-- 检查是否有过于复杂的布尔返回代码段 -->
<module name="SimplifyBooleanReturn"/>
<!-- 类设计检查 -->
<!-- 检查类是否为扩展设计l -->
<!-- <module name="DesignForExtension"/> -->
<!-- 检查只有private构造函数的类是否声明为final -->
<module name="FinalClass"/>
<!-- 检查工具类是否有putblic的构造器 -->
<module name="HideUtilityClassConstructor"/>
<!-- 检查接口是否仅定义类型 -->
<module name="InterfaceIsType"/>
<!-- 检查类成员的可见度 -->
<module name="VisibilityModifier"/>
<!-- 其他检查 -->
<!-- 文件中使用了System.out.print等
<module name="GenericIllegalRegexp">
<property name="format" value="System\.out\.print"/>
</module>
<module name="GenericIllegalRegexp">
<property name="format" value="System\.exit"/>
</module>
<module name="GenericIllegalRegexp">
<property name="format" value="printStackTrace"/>
</module>-->
<!-- 代码质量 -->
<!-- 圈复杂度
<module name="CyclomaticComplexity">
<property name="max" value="2"/>
</module> -->
</module>
</module>`
另外还有 Google、华为在网上发布的规范xml(下载的有直接查看即可)
Checkstyle 书写规则
Checkstyle的检查原理
sun_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。
standard checks中的一些具体用法
1. Javadoc Comments
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。
2. Naming Conventions
AbstractClassName
检查抽象类名。
ClassTypeParameterName
检查类的Parameter名。
ConstantName
检查常量名。
LocalFinalVariableName
检查局部的final类型变量名,包括catch的参数。
LocalVarableName
检查局部的非final类型的变量名,包括catch的参数。
MemberName
检查非静态变量。
MethodName
检查方法名。
MethodTypeParameterName
检查方法的参数名。
PackageName
检查包名。
ParameterName
检查参数名。
StaticVariableName
检查静态的,非final类型的变量名。
TypeName
检查类名和接口名。
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文件来指定。
4. Size Violations
ExecutableStatementCount
限制可执行代码片段的长度。默认为30。
FileLength
检查java文件的长度。默认为2000。
LineLength
检查代码行的长度。默认为80。
MethodLength
检查方法和构造函数的长度。默认为150。
AnonInnerLength
检查匿名内部类的长度。默认为20。
ParameterNumber
检查方法和构造函数的参数个数。默认为7。
5. Whitespace
GenericWhitespace
检查<和>周围的空白。
EmptyForInitializerPad
检查空的初始化位置的空白。比如for循环中的初始化。
EmptyForIteratorPad
检查空的迭代位置的空白。
MethodParamPad
检查方法签名之前的空白。
NoWhitespaceAfter
检查分隔符后的空白。
NoWhitespaceBefore
检查分隔符前的空白。
OperatorWrap
检查操作符的空白规则。
ParenPad
检查圆括号的空白规则。
TypecaseParenPad
检查强制转型的圆括号的空白规则。
TabCharacter
检查是否有Tab字符(’"t’)。
WhitespaceAfter
检查分隔符是否在空白之后。
WhitespaceAround
检查分隔符周围是否有空白。
6. ModifierOrder
ModifierOrder
检查修饰符的顺序是否遵照java语言规范。
RedundantModifier
检查接口和annotation中是否有重复的修饰符。
7. Block Checks
EmptyBlock
检查空的代码块。
LeftCurly
检查’{’和左边的代码块是否在同一行。
NeedBraces
检查是否需要大括号。主要是在if,else时的情况。
RightCurly
检查’}’。
AvoidNestedBlocks
检查不需要的嵌套’{}’。
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
检查是否有使用不需要的圆括号。
VisibilityModifier
检查类成员的可见度。
FinalClass
检查只有private构造函数的类是否声明为final。
InterfaceIsType
检查接口是否仅定义类型。
HideUtilityClassConstructor
检查工具类是否有putblic的构造器。
DesignForExension
检查类是否为扩展设计。
MutableException
确保异常是不可变的。
ThrowsCount
限制抛出异常的数量。
9. Duplicate Code
StrictDuplicateCode
严格检查重复代码。
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/,官网上对于每一检查项及其配置信息都讲解得很详细。