CheckStyle官方文档: CheckStyle官方文档

最近使用CheckStyle进行团队开发的代码规范管理,使得代码阅读起来更加舒适,编写代码更加符合规范,对官方文档一顿查看。感慨我怎么现在才使用这个好东西,希望大家有需要的都用起来,要相信好的工具不仅会让工作变得轻松,而且会让你变得更好。

刚开始我也是找Google的CheckStyle模板进行修改,但因为没有看官方文档看起来配起来也是挺吃力的,所以就一咬牙一跺脚花了个晚上把官方文档过了。写了一个自己的模板。希望对大家有一定帮助。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE module PUBLIC
        "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
        "https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
    <!--编码字符集-->
    <property name="charset" value="UTF-8"/>
    <property name="severity" value="warning"/>
    <property name="fileExtensions" value="java"/>
    <module name="FileTabCharacter">
        <property name="eachLine" value="true"/>
    </module>
    <!--检查项规则配置-->
    <module name="TreeWalker">
        <!--
            1.Annotation检查:
                AnnotationLocation:注解规范
                AnnotationOnSameLine:注解同行规范
                AnnotationUseStyle:注解风格检查
        -->
        <module name="AnnotationLocation">
            <!--注解应该独占一行-->
            <property name="allowSamelineMultipleAnnotations" value="false"/>
            <property name="allowSamelineSingleParameterlessAnnotation" value="false"/>
            <property name="allowSamelineParameterizedAnnotation" value="false"/>
            <!--检查对象:类、接口、枚举、方法、构造器、变量-->
            <property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
        </module>
        <module name="AnnotationOnSameLine">
            <!--检查对象:参数-->
            <property name="tokens" value="PARAMETER_DEF" />
        </module>
        <module name="AnnotationUseStyle">
            <property name="elementStyle" value="expanded"/>
            <property name="trailingArrayComma" value="never"/>
            <property name="closingParens" value="never"/>
        </module>
        <!--
            2.Block 检查:
                AvoidNestedBlocks: 内嵌代码块检查
                EmptyBlock:
                EmptyCatchBlock:
                LeftCurly: 左花括号检查
                RightCurly: 右花括号检查
                NeedBraces: if (obj.isValid()) return true; // OK
        -->
        <!--关闭这个检查,因为通常我们是要使用代码块的,比如说:Switch\静态代码块-->
        <!--<module name="AvoidNestedBlocks"/>-->
        <module name="EmptyBlock">
            <property name="option" value="statement"/>
        </module>
        <module name="EmptyCatchBlock">
            <property name="commentFormat" value="This is expected"/>
            <property name="exceptionVariableName" value="myException"/>
        </module>
        <module name="NeedBraces">
            <property name="allowSingleLineStatement" value="true"/>
        </module>
        <module name="LeftCurly">
            <!--
                可选值有:(可查看官方文档Property Types) http://checkstyle.sourceforge.net/property_types.html#lcurly
                    eol: end of the line
                    nl: new line
                    nlow: new line on wrap
             -->
            <property name="option" value="eol"/>
            <property name="ignoreEnums" value="true"/>
            <property name="tokens" value="ANNOTATION_DEF, CLASS_DEF, CTOR_DEF, INTERFACE_DEF, LITERAL_CATCH, LITERAL_DEFAULT, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, METHOD_DEF, STATIC_INIT"/>
        </module>
        <module name="RightCurly">
            <!--
                可选值有:(可查看官方文档Property Types) http://checkstyle.sourceforge.net/property_types.html#rcurly
                    alone: 独占一行
                    alone_or_singleline: 独占一行或者single line格式:private void set(){ a = 1; }
                    same: 跟alone_or_singleline类似,但多块语句时必须在同一行,如 } else 必须在同一行
             -->
            <property name="option" value="alone"/>
            <property name="tokens" value="LITERAL_FINALLY, LITERAL_ELSE, CLASS_DEF, METHOD_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT"/>
        </module>
        <!--
            3.Class设计检查:
                DesignForExtension:
                OneTopLevelClass:
                InterfaceIsType:
                InnerTypeLast:
                HideUtilityClassConstructor:
                FinalClass:
                ThrowsCount:
                VisibilityModifier:
        -->
        <module name="DesignForExtension">
            <property name="ignoredAnnotations" value="Override, Test"/>
        </module>
        <module name="OneTopLevelClass"/>
        <module name="InterfaceIsType"/>
        <module name="InnerTypeLast"/>
        <module name="HideUtilityClassConstructor"/>
        <module name="FinalClass"/>
        <module name="ThrowsCount">
            <property name="max" value="3"/>
        </module>
        <module name="VisibilityModifier"/>
        <!--
            4.coding检查:
                ArrayTrailingComma:
                AvoidInlineConditionals:
                CovariantEquals:
                DeclarationOrder:
                DefaultComesLast:
                EmptyStatement:
                EqualsAvoidNull:
                EqualsHashCode:
                ExplicitInitialization:
                FallThrough:
                FinalLocalVariable:
                HiddenField:
                MissingSwitchDefault:
                MissingCtor:
                MagicNumber:
                ModifiedControlVariable:
                MultipleVariableDeclarations:
                NestedForDepth:
                NestedIfDepth:
                NestedTryDepth:
                NoFinalizer:
                OneStatementPerLine:
                OverloadMethodsDeclarationOrder:
                PackageDeclaration:
                ParameterAssignment:
                ReturnCount:
                VariableDeclarationUsageDistance:
        -->
        <module name="ArrayTrailingComma"/>
        <module name="AvoidInlineConditionals"/>
        <module name="CovariantEquals"/>
        <module name="DeclarationOrder"/>
        <module name="DefaultComesLast"/>
        <module name="EmptyStatement"/>
        <module name="EqualsAvoidNull"/>
        <module name="EqualsHashCode"/>
        <module name="ExplicitInitialization"/>
        <module name="FallThrough"/>
        <module name="FinalLocalVariable"/>
        <module name="HiddenField"/>
        <module name="MissingSwitchDefault"/>
        <module name="MagicNumber"/>
        <module name="ModifiedControlVariable"/>
        <module name="MultipleVariableDeclarations"/>
        <module name="NestedForDepth">
            <property name="max" value="3"/>
        </module>
        <module name="NestedIfDepth">
            <property name="max" value="4"/>
        </module>
        <module name="NestedTryDepth">
            <property name="max" value="3"/>
        </module>
        <module name="NoFinalizer"/>
        <module name="OneStatementPerLine"/>
        <module name="OverloadMethodsDeclarationOrder"/>
        <module name="PackageDeclaration"/>
        <module name="ParameterAssignment"/>
        <module name="ReturnCount">
            <property name="max" value="3"/>
        </module>
        <module name="VariableDeclarationUsageDistance">
            <property name="allowedDistance" value="4"/>
            <property name="ignoreVariablePattern" value="^temp.*"/>
            <property name="validateBetweenScopes" value="true"/>
            <property name="ignoreFinal" value="false"/>
        </module>
        <!--
            5.Import检查:
                AvoidStarImport:
                AvoidStaticImport:
                CustomImportOrder:
                RedundantImport:
                UnusedImports:
        -->
        <module name="AvoidStarImport">
            <property name="excludes" value="java.io,java.net,java.lang.Math"/>
            <property name="allowClassImports" value="false"/>
            <property name="allowStaticMemberImports" value="false"/>
        </module>
        <module name="AvoidStaticImport">
            <property name="excludes" value="java.lang.System.out,java.lang.Math.*"/>
        </module>
        <module name="CustomImportOrder"/>
        <module name="RedundantImport"/>
        <module name="UnusedImports"/>
        <!--
            6.Javadoc检查:
                AtclauseOrder:
                JavadocMethod:
                JavadocTagContinuationIndentation:
                JavadocParagraph:
                JavadocPackage:
                JavadocType:
                JavadocVariable:
                NonEmptyAtclauseDescription:
                SingleLineJavadoc:
                SummaryJavadoc:
        -->
        <module name="AtclauseOrder">
            <property name="tagOrder" value="@author, @version, @param, @return, @throws, @exception"/>
            <property name="target" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
        </module>
        <module name="JavadocMethod">
            <!--public:只有public修饰的才检查,private:全部都检查-->
            <property name="scope" value="private"/>
            <property name="allowUndeclaredRTE" value="true"/>
            <property name="allowMissingReturnTag" value="true"/>
            <property name="allowMissingParamTags" value="true"/>
            <property name="allowMissingThrowsTags" value="true"/>
            <property name="allowMissingPropertyJavadoc" value="true"/>
            <property name="ignoreMethodNamesRegex" value="main"/>
            <property name="tokens" value="METHOD_DEF, ANNOTATION_FIELD_DEF"/>
        </module>
        <module name="JavadocTagContinuationIndentation">
            <property name="offset" value="4"/>
        </module>
        <module name="JavadocParagraph"/>
        <module name="JavadocType">
            <property name="allowMissingParamTags" value="true"/>
            <property name="allowUnknownTags" value="true"/>
        </module>
        <module name="JavadocVariable"/>
        <module name="NonEmptyAtclauseDescription"/>
        <module name="SingleLineJavadoc">
            <property name="ignoredTags" value="@inheritDoc, @see"/>
            <property name="ignoreInlineTags" value="false"/>
        </module>
        <module name="SummaryJavadoc">
            <property name="violateExecutionOnNonTightHtml" value="true" />
            <property name="forbiddenSummaryFragments" value="^$"/>
            <property name="period" value="" />
        </module>
        <module name="WriteTag">
            <property name="tag" value="@return"/>
            <property name="severity" value="ignore"/>
            <property name="tagSeverity" value="warning"/>
        </module>
        <!--
            7.Miscellaneous检查:
        -->
        <module name="ArrayTypeStyle">
            <property name="javaStyle" value="true"/>
        </module>
        <module name="AvoidEscapedUnicodeCharacters"/>
        <module name="CommentsIndentation"/>
        <module name="Indentation">
            <property name="basicOffset" value="4"/>
            <property name="braceAdjustment" value="0"/>
            <property name="caseIndent" value="4"/>
            <property name="throwsIndent" value="4"/>
            <property name="lineWrappingIndentation" value="4"/>
            <property name="arrayInitIndent" value="2"/>
        </module>
        <module name="TodoComment"/>
        <module name="TrailingComment"/>
        <module name="UpperEll"/>
        <!--
            8.命名检查
        -->
        <module name="AbbreviationAsWordInName"/>
        <module name="AbstractClassName">
            <property name="ignoreModifier" value="true"/>
        </module>
        <module name="CatchParameterName"/>
        <module name="ClassTypeParameterName"/>
        <module name="ConstantName"/>
        <module name="InterfaceTypeParameterName">
            <property name="format" value="^[a-zA-Z]$"/>
        </module>
        <module name="LambdaParameterName"/>
        <module name="LocalFinalVariableName"/>
        <module name="LocalVariableName"/>
        <module name="MemberName">
            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
        </module>
        <module name="MethodName">
            <property name="format" value="^[a-z]([a-zA-Z0-9])*$"/>
        </module>
        <module name="MethodTypeParameterName">
            <property name="format" value="^[a-zA-Z]$"/>
        </module>
        <module name="PackageName">
            <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
        </module>
        <module name="ParameterName">
            <property name="format" value="^[a-z][_a-zA-Z0-9]+$"/>
        </module>
        <module name="StaticVariableName">
            <property name="format" value="^[a-z](_?[a-zA-Z0-9]+)*$"/>
        </module>
        <module name="TypeName">
            <property name="format" value="^[A-Z](_?[a-zA-Z0-9]+)*$"/>
        </module>
        <module name="TypeName">
            <property name="format"
                      value="^I_[a-zA-Z0-9]*$"/>
            <property name="tokens"
                      value="INTERFACE_DEF"/>
        </module>
        <!--
            9.空格检查
                该检查是为了增加代码的可读性、可维护性
        -->
        <module name="EmptyForInitializerPad">
            <property name="option" value="nospace"/>
        </module>
        <module name="EmptyForIteratorPad">
            <property name="option" value="space"/>
        </module>
        <module name="EmptyLineSeparator">
            <property name="tokens" value="VARIABLE_DEF, METHOD_DEF"/>
        </module>
        <module name="MethodParamPad">
            <property name="tokens" value="METHOD_DEF"/>
            <property name="option" value="nospace"/>
            <property name="allowLineBreaks" value="true"/>
        </module>
        <module name="NoLineWrap">
            <property name="tokens" value="IMPORT"/>
        </module>
        <module name="NoWhitespaceAfter">
            <property name="tokens" value="DOT"/>
            <property name="allowLineBreaks" value="false"/>
        </module>
        <module name="NoWhitespaceBefore">
            <property name="tokens" value="DOT"/>
            <property name="allowLineBreaks" value="true"/>
        </module>
        <module name="OperatorWrap"/>
        <module name="ParenPad"/>
        <module name="SingleSpaceSeparator"/>
        <module name="TypecastParenPad">
            <property name="option" value="space"/>
        </module>
        <module name="WhitespaceAfter">
            <property name="tokens" value="COMMA, SEMI, TYPECAST, LITERAL_ELSE"/>
        </module>
        <module name="WhitespaceAround">
            <!--else、catch、finally、赋值符、运算符、连接符-->
            <property name="tokens" value="ASSIGN, BOR, BOR_ASSIGN, EQUAL, GE, GT, LAMBDA, LAND, LE, LITERAL_CATCH, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_SYNCHRONIZED, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, SL, SL_ASSIGN, SR, SR_ASSIGN, STAR, STAR_ASSIGN"/>
        </module>
        <!--
            10.Size检查:依然是解决可读性
                方法体大小、文件大小等
        -->
        <module name="AnonInnerLength">
            <property name="max" value="80"/>
        </module>
        <module name="ExecutableStatementCount"/>
        <module name="LineLength">
            <property name="max" value="120"/>
        </module>
        <module name="MethodCount">
            <property name="maxTotal" value="30"/>
        </module>
        <module name="MethodLength">
            <property name="tokens" value="METHOD_DEF"/>
            <property name="max" value="80"/>
            <property name="countEmpty" value="false"/>
        </module>
        <module name="OuterTypeNumber"/>
        <module name="ParameterNumber"/>
    </module>
</module>

备注:上面的文档是按照官方排版编写,并且是根据我自己关注的点进行配置,并不包含所有的配置节点,所以你如果要跟详细的配置,可以自行进入官方文档查看。其实这个东西配置起来费劲的地方是:你要知道你想要的代码风格对应的module节点叫啥,另外就是对应节点下面的属性有那些,对应属性的 可选值有哪些,可选值对应的效果有哪些。 我不知道现在市面上有没有对应这个插件的图形配置插件,如果有那就更加完美了,不用每次去翻阅文档来配置xml文档了(人总是这样得寸进尺,哈哈),不过这个东西你只要配置一次就够了,保存为模板,存储起来,要用就拿出来拷贝一份,如果有更新就修改修改(当然还是得看官方文档哟)。