后端必知:遵循Google Java规范并引入checkstyle检查

news2024/9/20 1:04:59

IDEA配置Code Style

协同工作时,为了保证统一的代码风格,要求我们使用的规范,如果大家都用的是 IDEA,则推荐使用 Google Code Style,推荐阅读Google Java 编程风格中文文档。

先下载配置文件:github.com/google/styl…

以上是我的 code 配置,一般缩进就是 2个字符。

格式化代码快捷键,window上快捷键为(Ctrl + Alt + L),mac 上为 ⌥ + ⌘ + L。

Maven项目引入checkstyle检查

由于项目是 Maven 项目,希望在编译的时候自动执行检查,不需要额外手动执行,可以选择在 pom.xml 配置 maven-checkstyle-plugin插件,绑定到 Maven 的生命周期,这样在执行 mvn compile 等命令时自动触发执行检查。

引入依赖

一 maven 项目 pom 引入 checkstyle 依赖

多模块的 maven 项目,只需要在父模块的 pom.xml 里面配置插件即可,pom.xml 配置如下:

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-checkstyle-plugin</artifactId>
      <version>3.2.0</version>
      <configuration>
        <configLocation>checkstyle.xml</configLocation>
        <consoleOutput>true</consoleOutput>
        <failsOnError>true</failsOnError>
        <linkXRef>false</linkXRef>
      </configuration>
      <executions>
        <execution>
          <id>validate</id>
          <phase>validate</phase>
          <goals>
            <goal>check</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
复制代码

checkstyle配置

二、下载 Google-checks.xml,下载地址:github.com/checkstyle/…

在项目中的位置如下所示:

下面是个人用的 checkstyle.xml 配置:

<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
  "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
  "https://checkstyle.org/dtds/configuration_1_3.dtd">

<!--
    Checkstyle configuration that checks the Google coding conventions from Google Java Style
    that can be found at https://google.github.io/styleguide/javaguide.html

    Checkstyle is very configurable. Be sure to read the documentation at
    http://checkstyle.org (or in your downloaded distribution).

    To completely disable a check, just comment it out or delete it from the file.
    To suppress certain violations please review suppression filters.

    Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
 -->

<module name="Checker">
  <module name="SuppressWarningsFilter"/>

  <property name="charset" value="UTF-8"/>
  <!-- 检查出问题的错误级别,这里设置为 error,目的是便于 Maven 构建时,能在检查出问题后使构建失败. -->
  <property name="severity" value="error"/>
  <!-- 本 checkstyle 检查哪些文件. -->
  <property name="fileExtensions" value="java, properties, xml"/>
  <!-- Excludes all 'module-info.java' files              -->
  <!-- See https://checkstyle.org/config_filefilters.html -->
  <module name="BeforeExecutionExclusionFileFilter">
    <property name="fileNamePattern" value="module\-info\.java$"/>
  </module>
  <!-- 配置抑制对某些文件进行检测的过滤器文件,默认是在 checkstyle-suppressions.xml 文件中. -->
  <!-- 具体如何进行配置可参考这里: https://checkstyle.org/config_filters.html#SuppressionFilter -->
  <module name="SuppressionFilter">
    <property name="file" value="${org.checkstyle.google.suppressionfilter.config}"
      default="checkstyle-suppressions.xml"/>
    <property name="optional" value="true"/>
  </module>

  <!-- Checks for whitespace                               -->
  <!-- 检查源代码中是否有制表符 (`tab`),默认检查每一行,
       更多配置可参考这里: http://checkstyle.org/config_whitespace.html. -->
  <module name="FileTabCharacter">
    <property name="eachLine" value="true"/>
  </module>

  <!-- 列长度限制,这里我定义为 150,且对于含有 package, import, http 等关键字的忽略其列长度限制. -->
  <module name="LineLength">
    <property name="fileExtensions" value="java"/>
    <property name="max" value="150"/>
    <property name="ignorePattern"
      value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
  </module>

  <module name="TreeWalker">
    <module name="OuterTypeFilename"/>
    <!-- 检查非法的字符串标记,不使用八进制数和 Unicode 转义符. -->
    <module name="IllegalTokenText">
      <property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
      <property name="format"
        value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
      <property name="message"
        value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
    </module>
    <!-- 避免转义的 Unicode 字符,这里允许各种转义字符和对其进行尾部注释. -->
    <module name="AvoidEscapedUnicodeCharacters">
      <property name="allowEscapesForControlCharacters" value="true"/>
      <property name="allowByTailComment" value="true"/>
      <property name="allowNonPrintableEscapes" value="true"/>
    </module>
    <!-- 检查是否使用 '*' 号导入,是否只有一个顶级类,包语句和导入语句不需要换行的情况. -->
    <module name="AvoidStarImport"/>
    <module name="OneTopLevelClass"/>
    <module name="NoLineWrap">
      <property name="tokens" value="PACKAGE_DEF, IMPORT, STATIC_IMPORT"/>
    </module>
    <!-- 检查是否存在空语句块的情况,包括:while, do, for, if 等等. -->
    <module name="EmptyBlock">
      <property name="option" value="TEXT"/>
      <property name="tokens"
        value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
    </module>
    <!-- 检查需要双大括号 ('{', '}') 语句块的情况,包括:while, do, for, if, else. -->
    <module name="NeedBraces">
      <property name="tokens"
        value="LITERAL_DO, LITERAL_ELSE, LITERAL_FOR, LITERAL_IF, LITERAL_WHILE"/>
    </module>
    <!-- 检查左大括号 ('{') 及之前的代码须在一行的情况,包括:类定义, Lambda, for, finally, if 等等. -->
    <module name="LeftCurly">
      <property name="tokens"
        value="ANNOTATION_DEF, CLASS_DEF, CTOR_DEF, ENUM_CONSTANT_DEF, ENUM_DEF,
                    INTERFACE_DEF, LAMBDA, LITERAL_CASE, LITERAL_CATCH, LITERAL_DEFAULT,
                    LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF,
                    LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, METHOD_DEF,
                    OBJBLOCK, STATIC_INIT, RECORD_DEF, COMPACT_CTOR_DEF"/>
    </module>
    <!-- 检查右大括号 ('}') 与之后的代码在同一行情况,包括:try, catch, finally, if, else, do 等等. -->
    <module name="RightCurly">
      <property name="id" value="RightCurlySame"/>
      <property name="tokens"
        value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE,
                    LITERAL_DO"/>
    </module>
    <!-- 检查右大括号 ('}') 独立成行的情况,包括:类定义,方法定义,for, while, static 代码块等. -->
    <module name="RightCurly">
      <property name="id" value="RightCurlyAlone"/>
      <property name="option" value="alone"/>
      <property name="tokens"
        value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT,
                    INSTANCE_INIT, ANNOTATION_DEF, ENUM_DEF, INTERFACE_DEF, RECORD_DEF,
                    COMPACT_CTOR_DEF"/>
    </module>
    <!-- 单个规则抑制过滤器,包含 XPath 元素和表达式的抑制。详情可参考这里:
            https://github.com/checkstyle/checkstyle/issues/7541 -->
    <module name="SuppressionXpathSingleFilter">
      <property name="id" value="RightCurlyAlone"/>
      <property name="query" value="//RCURLY[parent::SLIST[count(./*)=1]
                                     or preceding-sibling::*[last()][self::LCURLY]]"/>
    </module>
    <!-- 检查特殊符号后面是否有空格. -->
    <module name="WhitespaceAfter">
      <property name="tokens"
        value="COMMA, SEMI, TYPECAST, LITERAL_IF, LITERAL_ELSE,
                    LITERAL_WHILE, LITERAL_DO, LITERAL_FOR, DO_WHILE"/>
    </module>
    <!-- 检查标识符周围是否有空白,空构造方法,空方法,空注解,空循环等的大括号中必须有空白,通常是空行. -->
    <module name="WhitespaceAround">
      <property name="allowEmptyConstructors" value="true"/>
      <property name="allowEmptyLambdas" value="true"/>
      <property name="allowEmptyMethods" value="true"/>
      <property name="allowEmptyTypes" value="true"/>
      <property name="allowEmptyLoops" value="true"/>
      <property name="ignoreEnhancedForColon" value="false"/>
      <property name="tokens"
        value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR,
                    BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, DO_WHILE, EQUAL, GE, GT, LAMBDA, LAND,
                    LCURLY, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY,
                    LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SWITCH, LITERAL_SYNCHRONIZED,
                    LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN,
                    NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, RCURLY, SL, SLIST, SL_ASSIGN, SR,
                    SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND"/>
      <message key="ws.notFollowed"
        value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks
               may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
      <message key="ws.notPreceded"
        value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
    </module>
    <!-- 检查每行只能有一条语句和不能多变量声明. -->
    <module name="OneStatementPerLine"/>
    <module name="MultipleVariableDeclarations"/>
    <!-- 检查数组类型的风格,默认强制使用 Java 风格,即中括号紧跟在类型后面,如:'String[] arr'. -->
    <module name="ArrayTypeStyle"/>
    <!-- 检查 switch 是否有 default 分支,及“直落注释”的检查. -->
    <module name="MissingSwitchDefault"/>
    <module name="FallThrough"/>
    <!-- 检查 long 型变量值是否以大写的 'L' 结尾. -->
    <module name="UpperEll"/>
    <!-- 检查修饰符的顺序是否符合 Java 语言规范. 顺序应该是:'public protected private abstract default static final
           transient volatile synchronized native strictfp'. -->
    <module name="ModifierOrder"/>
    <!-- 检查主要分割模块之间是否有空行,包括:包语句,导入语句、静态导入、类定义、方法定义等等. -->
    <module name="EmptyLineSeparator">
      <property name="tokens"
        value="PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
                    STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF, VARIABLE_DEF, RECORD_DEF,
                    COMPACT_CTOR_DEF"/>
      <!-- 允许字段之间没有空行,不允许模块间或模块类有多个空行(即最多只有一个空行). -->
      <property name="allowNoEmptyLineBetweenFields" value="true"/>
    </module>
    <!-- 检查在英文点号 ('.') 处换行,且英文点号需在下一行的行首 (即:'nl'). -->
    <module name="SeparatorWrap">
      <property name="id" value="SeparatorWrapDot"/>
      <property name="tokens" value="DOT"/>
      <property name="option" value="nl"/>
    </module>
    <!-- 检查在英文逗号 (',') 处换行,且英文逗号需在上一行的行尾 (即:'eol'). -->
    <module name="SeparatorWrap">
      <property name="id" value="SeparatorWrapComma"/>
      <property name="tokens" value="COMMA"/>
      <property name="option" value="EOL"/>
    </module>
    <!-- 检查在省略号 ('...') 处换行,且省略号需在上一行的行尾 (即:'eol'). -->
    <module name="SeparatorWrap">
      <!-- ELLIPSIS is EOL until https://github.com/google/styleguide/issues/259 -->
      <property name="id" value="SeparatorWrapEllipsis"/>
      <property name="tokens" value="ELLIPSIS"/>
      <property name="option" value="EOL"/>
    </module>
    <!-- 检查在数组中括号 ('[]') 处换行,且中括号需在上一行的行尾 (即:'eol'). -->
    <module name="SeparatorWrap">
      <!-- ARRAY_DECLARATOR is EOL until https://github.com/google/styleguide/issues/258 -->
      <property name="id" value="SeparatorWrapArrayDeclarator"/>
      <property name="tokens" value="ARRAY_DECLARATOR"/>
      <property name="option" value="EOL"/>
    </module>
    <!-- 检查在方法引用双冒号 ('::') 处换行,且双冒号需在下一行的行首 (即:'nl'). -->
    <module name="SeparatorWrap">
      <property name="id" value="SeparatorWrapMethodRef"/>
      <property name="tokens" value="METHOD_REF"/>
      <property name="option" value="nl"/>
    </module>
    <!-- 检查包 (package) 名称是否符合 format 中定义的属性指定的格式. -->
    <module name="PackageName">
      <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
      <message key="name.invalidPattern"
        value="Package name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 检查类型名称(类、接口、枚举、注解等)是否符合大驼峰的格式. -->
    <module name="TypeName">
      <property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
                    ANNOTATION_DEF, RECORD_DEF"/>
      <message key="name.invalidPattern"
        value="Type name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 检查类成员名称(属性、方法)是否符合 format 中定义的小驼峰格式. -->
    <module name="MemberName">
      <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
      <message key="name.invalidPattern"
        value="Member name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 检查参数名称是否符合 format 中定义的小驼峰格式. -->
    <module name="ParameterName">
      <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
      <message key="name.invalidPattern"
        value="Parameter name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 检查 Lambda 参数名称是否符合 format 中定义的小驼峰格式. -->
    <module name="LambdaParameterName">
      <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
      <message key="name.invalidPattern"
        value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 检查 Catch 块中参数名称是否符合 format 中定义的小驼峰格式. -->
    <module name="CatchParameterName">
      <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
      <message key="name.invalidPattern"
        value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 检查局部变量名称是否符合 format 中定义的小驼峰格式. -->
    <module name="LocalVariableName">
      <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
      <message key="name.invalidPattern"
        value="Local variable name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 检查模式变量名称是否符合 format 中定义的小驼峰格式,可以参见 Java 14 中的 instanceOf 模式匹配功能. -->
    <module name="PatternVariableName">
      <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
      <message key="name.invalidPattern"
        value="Pattern variable name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 检查类中的泛型参数名称是否符合 format 中定义的格式. -->
    <module name="ClassTypeParameterName">
      <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
      <message key="name.invalidPattern"
        value="Class type name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 检查 Record 类中,组件名称是否符合 format 中定义的小驼峰格式. -->
    <module name="RecordComponentName">
      <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$" />
      <message key="name.invalidPattern" value="Record component name ''{0}'' must match pattern ''{1}''." />
    </module>
    <!-- 检查 Record 泛型参数名称是否符合 format 中定义的格式. -->
    <module name="RecordTypeParameterName">
      <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
      <message key="name.invalidPattern"
        value="Record type name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 检查 Record 泛型参数名称是否符合 format 中定义的格式. -->
    <module name="RecordTypeParameterName">
      <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
      <message key="name.invalidPattern"
        value="Record type name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 检查方法中的的泛型参数名称是否符合 format 中定义的格式. -->
    <module name="MethodTypeParameterName">
      <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
      <message key="name.invalidPattern"
        value="Method type name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 检查接口中的的泛型参数名称是否符合 format 中定义的格式. -->
    <module name="InterfaceTypeParameterName">
      <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
      <message key="name.invalidPattern"
        value="Interface type name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 检查是否重写了 `Object.finalize` 方法(禁止重写). -->
    <module name="NoFinalizer"/>
    <!-- 检查尖括号 ('<', '>') 周围的空白,详情参考这里:
            https://checkstyle.sourceforge.io/config_whitespace.html#GenericWhitespace. -->
    <module name="GenericWhitespace">
      <message key="ws.followed"
        value="GenericWhitespace ''{0}'' is followed by whitespace."/>
      <message key="ws.preceded"
        value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
      <message key="ws.illegalFollow"
        value="GenericWhitespace ''{0}'' should followed by whitespace."/>
      <message key="ws.notPreceded"
        value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
    </module>
    <!-- 检查缩进的空格数是否正确,基础缩进是 2 格,抛出异常和换行是 4 格. -->
    <module name="Indentation">
      <property name="basicOffset" value="2"/>
      <property name="braceAdjustment" value="0"/>
      <property name="caseIndent" value="2"/>
      <property name="throwsIndent" value="4"/>
      <property name="lineWrappingIndentation" value="4"/>
      <property name="arrayInitIndent" value="2"/>
    </module>
    <!-- 检查标识符名称中的缩写(连续大写字母)长度,自定义了一些可以连续大写字母的单词,如:XML, ID, VO 等等. -->
    <module name="AbbreviationAsWordInName">
      <!--忽略常量中的连续大写字母-->
      <property name="ignoreFinal" value="false"/>
      <property name="allowedAbbreviationLength" value="0"/>
      <property name="allowedAbbreviations"
        value="XML, URL, ID, FTP, DTO, VO, DO, TO, PO, BO, POJO, HTTP, IP, IE"/>
      <property name="tokens"
        value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF, ANNOTATION_FIELD_DEF,
                    PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF, PATTERN_VARIABLE_DEF, RECORD_DEF,
                    RECORD_COMPONENT_DEF"/>
    </module>
    <!-- 检查 switch 块中冒号之前是否没有空格. -->
    <module name="NoWhitespaceBeforeCaseDefaultColon"/>
    <module name="OverloadMethodsDeclarationOrder"/>
    <!-- 检查变量声明与其首次使用之间的距离,默认大于 3 行,如果该变量是 final 修饰的,默认会忽略此规则. -->
    <module name="VariableDeclarationUsageDistance"/>
    <!-- 检查自定义导入 (import) 顺序,按 ASCII 码顺序对导入进行分组排序. -->
    <module name="CustomImportOrder">
      <property name="sortImportsInGroupAlphabetically" value="true"/>
      <property name="separateLineBetweenGroups" value="true"/>
      <property name="customImportOrderRules" value="STATIC###THIRD_PARTY_PACKAGE"/>
      <property name="tokens" value="IMPORT, STATIC_IMPORT, PACKAGE_DEF"/>
    </module>
    <!-- 检查方法定义,方法调用等情况与参数列表左括号之间无空格,在标识符与左括号之间也不允许换行(默认). -->
    <module name="MethodParamPad">
      <property name="tokens"
        value="CTOR_DEF, LITERAL_NEW, METHOD_CALL, METHOD_DEF,
                    SUPER_CTOR_CALL, ENUM_CONSTANT_DEF, RECORD_DEF"/>
    </module>
    <!-- 检查标记符之前没有空白. -->
    <module name="NoWhitespaceBefore">
      <property name="tokens"
        value="COMMA, SEMI, POST_INC, POST_DEC, DOT,
                    LABELED_STAT, METHOD_REF"/>
      <property name="allowLineBreaks" value="true"/>
    </module>
    <!-- 检查小括号 ('(', ')') 的空白填充策略,默认小括号内的两边没有空格. -->
    <module name="ParenPad">
      <property name="tokens"
        value="ANNOTATION, ANNOTATION_FIELD_DEF, CTOR_CALL, CTOR_DEF, DOT, ENUM_CONSTANT_DEF,
                    EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW,
                    LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL,
                    METHOD_DEF, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, LAMBDA,
                    RECORD_DEF"/>
    </module>
    <!-- 检查在运算符处换行的策略,且换行后运算符在下一行的行首,并定义了常见的运算符. -->
    <module name="OperatorWrap">
      <property name="option" value="NL"/>
      <property name="tokens"
        value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR,
                    LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR, METHOD_REF,
                    TYPE_EXTENSION_AND "/>
    </module>
    <!-- 检查注解的标注位置,该类注解必须独立成行,包括:类,接口,枚举,方法等处的注解定义. -->
    <module name="AnnotationLocation">
      <property name="id" value="AnnotationLocationMostCases"/>
      <property name="tokens"
        value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF,
                      RECORD_DEF, COMPACT_CTOR_DEF"/>
    </module>
    <!-- 检查局部变量注解的标注位置,该类注解允许在同一行. -->
    <module name="AnnotationLocation">
      <property name="id" value="AnnotationLocationVariables"/>
      <property name="tokens" value="VARIABLE_DEF"/>
      <property name="allowSamelineMultipleAnnotations" value="true"/>
    </module>
    <module name="NonEmptyAtclauseDescription"/>
    <!-- 检查 Javadoc 是否位于正确的位置,其会检查无效的 Javadoc. -->
    <module name="InvalidJavadocPosition"/>
    <!-- 检查 Javadoc 中 '@' 注解标签的缩进,默认换行时会缩进 4 格,此处自定义为0格. -->
    <module name="JavadocTagContinuationIndentation">
      <property name="offset" value="0"/>
    </module>
    <module name="SummaryJavadoc">
      <property name="forbiddenSummaryFragments"
        value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
    </module>
    <!-- 检查 Javadoc 中的段落. -->
    <module name="JavadocParagraph"/>
    <!-- 使用空行来隔开 '@Param'、'@return' 等块标签组. -->
    <module name="RequireEmptyLineBeforeBlockTagGroup"/>
    <!-- 约定 Javadoc 注解标记的先后顺序. -->
    <module name="AtclauseOrder">
      <!--<property name="tagOrder"
        value="@param, @return, @throws, @deprecated, @author, @博客, @网站, @date, @description"/>-->
      <property name="tagOrder" value="@param, @return, @throws, @deprecated, @author"/>
      <property name="target"
        value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
    </module>
    <!-- Javadoc 方法注释,检查 protected 及其之上的 protected 域,且不能缺失 @param 和 @return 的注解标记. -->
    <module name="JavadocMethod">
      <property name="accessModifiers" value="public"/>
      <property name="allowMissingParamTags" value="true"/>
      <property name="allowMissingReturnTag" value="true"/>
      <!-- Javadoc 方法注释,允许在具有 @Override 和 @Test 注解的方法上写 Javadoc 注释. -->
      <property name="allowedAnnotations" value="Override, Test"/>
      <property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF, COMPACT_CTOR_DEF"/>
    </module>
    <!-- 可以缺失的 Javadoc 方法注释,检查 protected 域,且最小代码行数小于 0 行时,才可缺失(即无论如何都不可缺失). -->
    <!--<module name="MissingJavadocMethod">
      <property name="scope" value="public"/>
      <property name="minLineCount" value="0"/>
      <property name="allowedAnnotations" value="Override, Test"/>
      <property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF,
                                   COMPACT_CTOR_DEF"/>
    </module> -->
    <!-- 检查类、枚举、接口和注解接口定义中缺少的 Javadoc 注释. -->
    <!--<module name="MissingJavadocType">
      <property name="scope" value="protected"/>
      <property name="tokens"
        value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
                      RECORD_DEF, ANNOTATION_DEF"/>
      <property name="excludeScope" value="nothing"/>
    </module>-->
    <!-- 方法名使用小驼峰的模式. -->
    <module name="MethodName">
      <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/>
      <message key="name.invalidPattern"
        value="Method name ''{0}'' must match pattern ''{1}''."/>
    </module>
    <!-- 单行的 Javadoc,不忽略行内标签. -->
    <module name="SingleLineJavadoc">
      <property name="ignoreInlineTags" value="false"/>
    </module>
    <!-- 检查允许空 catch 块的情况,通过将异常实例变量名命名为 'expected', 就会跳过该项的检查. -->
    <module name="EmptyCatchBlock">
      <property name="exceptionVariableName" value="expected"/>
    </module>
    <!-- 检查注释和周围代码之间的缩进.-->
    <module name="CommentsIndentation">
      <property name="tokens" value="SINGLE_LINE_COMMENT, BLOCK_COMMENT_BEGIN"/>
    </module>
    <!-- 规则抑制过滤器,包含 XPath 元素和表达式的抑制。详情可参考这里:
            https://checkstyle.org/config_filters.html#SuppressionXpathFilter -->
    <module name="SuppressionXpathFilter">
      <property name="file" value="${org.checkstyle.google.suppressionxpathfilter.config}"
        default="checkstyle-xpath-suppressions.xml"/>
      <property name="optional" value="true"/>
    </module>
    <module name="SuppressWarningsHolder"/>
    <!--抑制注释过滤器,以CHECKSTYLE.OFF开始,CHECKSTYLE.ON结束-->
    <module name="SuppressionCommentFilter">
      <property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/>
      <property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/>
      <property name="checkFormat" value="$1"/>
    </module>
    <module name="SuppressWithNearbyCommentFilter">
      <property name="commentFormat" value="CHECKSTYLE.SUPPRESS\: ([\w\|]+)"/>
      <!-- $1 refers to the first match group in the regex defined in commentFormat -->
      <property name="checkFormat" value="$1"/>
      <!-- The check is suppressed in the next line of code after the comment -->
      <property name="influenceFormat" value="1"/>
    </module>
  </module>
</module>
复制代码

执行 checkstyle 检查

执行命令

mvn checkstyle:check
//或者
mvn checkstyle:checkstyle
复制代码

或者点击如下命令:

SuppressionFilter

SuppressionFilter 可以抑制以 Treewalker 或 Checker 作为父模块的 Checks。

比如说我们的代码如下所示:

  private boolean isContainChinese(String text) {
    Pattern p = Pattern
        .compile("[\u4E00-\u9FA5!,。()《》“”?:;【】]");
    Matcher m = p.matcher(text);
    return m.find();
  }
复制代码

被检测出这样一个错误:

StringUtils.java:102:18: 不要使用Unicode转义字符。 [AvoidEscapedUnicodeCharacters]
复制代码

如何避免错误被检测呢,可以这样设置:

  <module name="SuppressionFilter">
    <property name="file" value="suppressions.xml"/>
    <property name="optional" value="true"/>
  </module>
复制代码

同时在 checkstyle.xml 所在目前下新建 suppressions.xml,内容如下:

<?xml version="1.0"?>

<!DOCTYPE suppressions PUBLIC
  "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
  "https://checkstyle.org/dtds/suppressions_1_2.dtd">

<suppressions>
  <suppress checks="AvoidEscapedUnicodeCharacters"
    files="StringUtils.java"
    lines="101-103"/>
  <suppress message="不要使用Unicode转义字符"/>
</suppressions>
复制代码

引入checkStyle插件

三、idea 中引入checkStyle插件

如果每次想针对单个文件执行 checkstyle 检查,可以这样做:

1、在IDEA中安装checstyle插件:

2、新增自定义的checkstyle.xml文件:

关于 suppressions 需要设置属性值,其实 checkstyle.xml 文件中已经有默认值了,但还需要设置,不然最后会报错。

最后效果如下:

3、随便进入一个文件,然后右键选择 checkstyle

执行效果如下:

重要检查及应对措施

关于 checkstyle 所有的检查通知,具体有哪些提示信息,参考这篇文章。这里贴一点提示信息:

indentation.error.multi=''{0}'' 缩进了{1}个缩进符,应为以下缩进之一:{2}。
indentation.child.error.multi=''{0}'' 子元素进了{1}个缩进符,应为以下缩进之一:{2}。
indentation.error=''{0}'' 缩进了{1}个缩进符,应为{2}个。
indentation.child.error=''{0}'' 子元素缩进了{1}个缩进符,应为{2}个。
comments.indentation.single=注释应与第{0}行代码同样缩进{2}个缩进符,而不是{1}个。
comments.indentation.block=注释应与第{0}行代码同样缩进{2}个缩进符,而不是{1}个。
复制代码

1、首先是方法注释,如果要求检查每个方法上是否有注释,则添加如下配置(默认自带)。位于 JavadocMethod model下,这点结合项目实际情况,按需决定是否需要保留。

比如说检查结果为:

BaseRedisConfig.java:30:3: 缺少 Javadoc 。 [MissingJavadocMethod]
复制代码

对应代码为:

  @Bean
  public RedisTemplate<String, Object> redisTemplate(
      RedisConnectionFactory redisConnectionFactory) {
    RedisSerializer<Object> serializer = redisSerializer();
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(redisConnectionFactory);
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(serializer);
    redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    redisTemplate.setHashValueSerializer(serializer);
    redisTemplate.afterPropertiesSet();
    return redisTemplate;
  }
复制代码

提示我们上述方法没有注释,如果想避开该检查,则删除如下配置。

<module name="MissingJavadocMethod">
  <property name="scope" value="public"/>
  <property name="minLineCount" value="2"/>
  <property name="allowedAnnotations" value="Override, Test"/>
  <property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF,
                                 COMPACT_CTOR_DEF"/>
</module>
<module name="MissingJavadocType">
  <property name="scope" value="protected"/>
  <property name="tokens"
            value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
                   RECORD_DEF, ANNOTATION_DEF"/>
  <property name="excludeScope" value="nothing"/>
</module>
复制代码

如果要求增加方法注释,则需要注意如下事项:

  1. 要包含方法说明
  2. 要包含参数列表
  3. 要包含返回值类型
  4. 要严格注意注释的缩进和星号数量

2、类注释

代码如下所示:

/**
 * @author hresh
 * @博客 https://juejin.cn/user/2664871918047063
 * @网站 https://www.hreshhao.com/
 * @date 2022/9/14 9:07 下午
 * @description
 */
@Configuration
public class SpringDocConfig{
  
}
复制代码

检查后提示如下信息:

SpringDocConfig.java:10: 缺少摘要javadoc。 [SummaryJavadoc]
复制代码

归根结底是因为类文件没有描述信息,@description 是我们自定义的标签,并不会 checkStyle 所认可,默认类文件描述信息要在第一行,且必须要有结尾标识,即添加英文句号结尾,如下所示:

/**
 * 测试.
 * 
 * @author hresh
 * @博客 https://juejin.cn/user/2664871918047063
 * @网站 https://www.hreshhao.com/
 * @date 2022/9/14 9:07 下午
 */
复制代码

这就要求我们修改类文件注释模版,如下所示:

/**
 * 
 *
 * @author hresh
 * @博客 https://juejin.cn/user/2664871918047063
 * @网站 https://www.hreshhao.com/
 * @date ${DATE} ${TIME} 
 */
复制代码

3、类注释缩进符不对

代码如下所示:

/**
 * @author hresh
 * @博客 https://juejin.cn/user/2664871918047063
 * @网站 https://www.hreshhao.com/
 * @date 2022/9/14 9:07 下午
 * @description
 */
@Configuration
public class SpringDocConfig{
  
}
复制代码

检查结果为:

SpringDocConfig.java:12: Javadoc 缩进级别错误,应为 4 个缩进符。 [JavadocTagContinuationIndentation]
SpringDocConfig.java:13: Javadoc 缩进级别错误,应为 4 个缩进符。 [JavadocTagContinuationIndentation]
复制代码

如何解决呢?最简单的方法就是去除该配置,除此之外,还需要修改类文件注释模版,如下是我自定义的模版:

/**
 * @author hresh
 * @博客 https://juejin.cn/user/2664871918047063
 * @网站 https://www.hreshhao.com/
 * @date ${DATE} ${TIME}
 * @description 
 */
复制代码

但仍然报错,经过测试发现,如果改成这样就不会检查报错了。

/*
 * @author hresh
 * @博客 https://juejin.cn/user/2664871918047063
 * @网站 https://www.hreshhao.com/
 * @date ${DATE} ${TIME}
 * @description 
 */
复制代码

经过查询 /* /和 /* */的区别,发现后者是说明注释,可以添加到 javadoc 中,后续可以生成 HTML 格式的代码报告。

最佳解决方案为:

<!-- 检查 Javadoc 中 '@' 注解标签的缩进,默认换行时会缩进 4 格,此处自定义为0格. -->
<module name="JavadocTagContinuationIndentation">
  <property name="offset" value="0"/>
</module>
复制代码

如何添加 property,以及 name 值是什么,这点需要参考官方文档: checkstyle.org/config_java…

4、方法参数名称

代码示例:

public static <T> PageResult<T> ok(IPage<T> iPage) 
复制代码

检查报错

Parameter name 'iPage' must match pattern '^[a-z]([a-z0-9][a-zA-Z0-9]*)?$'. [ParameterName]
复制代码

5、方法注释

代码示例:

/**
   * 驼峰转下划线
   *
   * @param name
   * @return
   */
public static String camelToUnderscore(String name) 
复制代码

上述代码会有两个报错:

StringUtils.java:15: Javadoc的第一句缺少一个结束时期。 [SummaryJavadoc]
StringUtils.java:18: @标签应有非空说明。 [NonEmptyAtclauseDescription]
复制代码

解决方案:

/**
   * 驼峰转下划线.
   *
   * @param name 字符串
   * @return
   */
public static String camelToUnderscore(String name)
复制代码

实际应用

当我们使用 orm-generator 脚手架生成模版代码,并复制到项目中后,格式可能存在问题,比如这种错误:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/102601.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

牛客竞赛每日俩题 - Day10

目录 输入输出的细节 函数find&#xff08;&#xff09;的用法 输入输出的细节 收件人列表__牛客网 细节一&#xff1a;当输入转行后又要使用getline&#xff08;&#xff09;时&#xff0c;必须先使用getchar&#xff08;&#xff09;吃掉前面的转行符\n;细节二&#xff1a…

介绍一个助你事半功倍的数据挖掘神器!!

在Pandas模块当中&#xff0c;对于表格数据的分组操作&#xff08;groupby&#xff09;和透视表&#xff08;pivot_table&#xff09;的制作一直都是比较常见的&#xff0c;今天小编为大家分享一个数据分析的利器&#xff0c;能够自动为我们完成上述提到的一系列操作&#xff0…

arcgis读取NetCDF格式的数据(c#读取数据)

项目里面要用到降雨的数据&#xff0c;正好是.NC格式的&#xff0c;以前也没用过&#xff0c;正好记录下&#xff0c;大家也可以参考下&#xff0c;首先是arcgis是如何处理NC数据的&#xff0c;在arcgis软件里面有个多维工具箱&#xff0c;我用的是汉化版本的&#xff0c;英文版…

[附源码]计算机毕业设计Python的剧本杀管理系统(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

Verilog 简易单周期CPU

目录 本实验包含&#xff1a; 简易结构图&#xff1a; 各部件代码或实现&#xff1a; 控制器&#xff1a; 寄存器堆&#xff1a; ALU&#xff1a; 数据存储器&#xff1a; 指令存储器&#xff1a; CPU&#xff1a; tp&#xff08;仿真文件&#xff09;&#xff1a; 仿真…

如何去掉idea的诸多警告

File->setting->Editor->inspections 选择漏斗&#xff0c;选中warning&#xff0c;筛选出所有警告级别&#xff0c;然后去掉勾选&#xff0c;然后重启idea即可

重构物理Entity架构,支持更多的形状

上一节实战如何编译BEPUphysicsint源码到自己的项目, 如何整合物理引擎与Unity图形渲染。本节来从新调整设计,让物理的Entity基本操作与物理的形状分离,支持更多的物理形状,支持物理entity与Unity物体位移与旋转同步。主要分成以下3个部分: 1: 设计PhyBaseEntity&#xff0c;让…

学到一招!PyCharm连接MySQL竟如此简单!

在 PyCharm 中是可以通过内置的工具来连接、操作数据库的&#xff0c;并且对于市面上大多数主流数据库都是支持的。 连接 MySQL 首先打开 PyCharm &#xff0c;点击菜单栏的 View --> Tool Windows --> Database 或者直接点击 PyCharm 右侧的 Database 然后就会在 PyCh…

【QT开发笔记-基础篇】| 第五章 绘图QPainter | 5.6 矩形、圆角矩形

本节对应的视频讲解&#xff1a;B_站_视_频 https://www.bilibili.com/video/BV1mg411J7u5 本节讲解如何绘制矩形、圆角矩形 1. 相关的 API 直接查看官方的帮助文档&#xff0c;可以看到有多个重载的方法用于绘制矩形、圆角矩形 1.1 矩形 // 带 F 表示参数为浮点数&#x…

【电商】电商系统---合同管理

说一下合同管理部分&#xff0c;希望对大家有帮助&#xff0c;如果大家觉得简单可以直接略过&#xff0c;谢谢&#xff01; 合同分类 合同主要分为采购类合同、销售类合同、其他合同。 采购合同和销售合同分别与采购订单和销售订单建立对应关系&#xff0c;通过采购订单和销售…

ChatGDP:人类未来世界的主宰

先简单介绍一下今天的主角——ChatGPT。 ChatGPT是一款由OpenAI开发的聊天机器人&#xff0c;它具有出色的自然语言处理能力&#xff0c;能够与人类进行真实的对话。它的核心技术是GPT-3语言模型&#xff0c;能够自动学习语言特征&#xff0c;并进行语义理解、文本生成等任务。…

HCL与Pipe、Autoit和MobaXterm的组合使用

我们平时做实验一般会用到真机或者是模拟器&#xff0c;因为我主要接触的都是一些H3C的产品和技术&#xff0c;所以模拟器用HCL会多一些。为了呈现出相对好一些的视觉效果&#xff0c;我一般会使用MobaXterm工具进行命令操作&#xff0c;所以大家看到的回显一般是这样的&#x…

哈工大视听觉信号处理——听觉部分报告——一种智能家居命令词识别系统的设计

题 目 听觉部分 专 业 软件工程 学   号 120L0219XX 班   级 2037101 姓 名 李启明 报 告 日 期 2022.12.20 一、基频 &#xff08;一&#xff…

肝了一周总结的SpringBoot常用注解大全,一目了然~

平时使用SpringBoot开发项目&#xff0c;少不了要使用到它的注解。这些注解让我们摆脱了繁琐的传统Spring XML配置&#xff0c;让我们开发项目更加高效&#xff0c;今天我们就来聊聊SpringBoot中常用的注解&#xff01; SpringBoot实战电商项目mall&#xff08;50kstar&#xf…

《c专家编程》读书笔记

《c专家编程》第一章 C&#xff1a;穿越时空的迷雾第二章 这不是Bug&#xff0c;而是语言特性gets实验第三章 分析C语言的声明const实验第四章 令人震惊的事实&#xff1a;数组和指针并不相同指针与数组实验第五章 对链接的思考简单静态库动态库实验第六章 运动的诗章&#xff…

python-(6-5-3)爬虫---修改代码

文章目录一 事件背景二 系统给的代码三 改进措施四 改进后的代码一 事件背景 本篇主要是生活分享。 公司研究了一个比较好玩的人工智能狗&#xff0c;我就想偷懒让它帮我写个代码&#xff0c;得到的漂亮小姐姐的照片&#xff0c;然后它还真的给我把代码弄出来了。 二 系统给的…

​九州一轨通过注册:计划募资6.57亿 京投公司为大股东

雷递网 雷建平 12月19日北京九州一轨环境科技股份有限公司(简称&#xff1a;“九州一轨”&#xff09;日前通过注册&#xff0c;准备在科创板上市。九州一轨计划募资6.57亿元&#xff0c;其中&#xff0c;2.79亿元用于噪声与振动综合控制产研基地建设项目&#xff0c;1.43亿元用…

[附源码]计算机毕业设计Python飞越青少儿兴趣培训机构管理系统(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等…

我的一周年创作纪念日

机缘 第一次写文章的时候&#xff0c;CSDN还是我平时课程设计的救星&#xff1b;第一次写文章的时候&#xff0c;还不知道有什么拿得出手、可以和大家分享的&#xff1b;第一次写文章的时候&#xff0c;幻想着自己一觉醒来就坐拥10w粉丝&#xff0c;哈哈哈。感谢自己曾经冒出的…

【实践】推荐、搜索、广告多业务多场景统一预估引擎实践与思考

省时查报告-专业、及时、全面的行研报告库省时查方案-专业、及时、全面的营销策划方案库【免费下载】2022年11月份热门报告盘点《底层逻辑》高清配图‍基于深度学习的个性化推荐系统实时化改造与升级.pdf推荐技术在vivo互联网商业化业务中的实践.pdf推荐系统基本问题及系统优化…