代码检查技术Checkstyle与p3c调研

代码检查技术Checkstyle与p3c调研

1.功能及差异

1.1 检查语言

代码检查JavaC语言javascript
Checkstyle××
P3c××

1.2 Jdk版本支持

代码检查支持jdk版本
CheckstyleCheckstyle7 >= jdk1.8
P3c>jdk1.6

1.3 使用方式

代码检查Idea插件Eclipse插件Maven插件命令独立执行
Checkstyle
P3c

1.4 工具差异

  • Checkstyle 支持sun,google,alibaba代码规范,提供100多条规则,可以使用方自己选择配置
  • P3c 基于《阿里巴巴JAVA开发手册》开发,实现了手册中的53条规则

2.接入java项目的可行性

2.1 Checkstyle

支持MAVEN插件的方式,执行编译打包命令mvn clean package会执行代码检查,
-Dcheckstyle-skip=true跳过代码检查。也可以使用java –jar checkstyle-8.24-all.jar命令执行检查。

2.2 P3c

支持MAVEN插件的方式,执行编译打包命令mvn clean package会执行代码检查,
-Dpmd.skip=true跳过代码检查。也可以用java -cp p3c-pmd.jar命令执行。

3.支持的检查项

3.1 Checkstyle

  1. 注解:注解规范、注解同行规范、注解风格检查

  2. 代码块:内嵌代码块检查、空代码块检查、空catch块检查,左右花括号检查…

  3. 类检查

  4. 编码检查:嵌套代码的深度,return的数量,检查数组初始化…

  5. 导入检查:无用导入检查、冗余导入…

  6. javadoc注释检查:方法/构造器javadoc检查、类javadoc检查…

  7. Miscellaneous(各种各样的)检查: 数组定义检查、todo注释…

  8. 命名检查

  9. 空格检查

  10. 大小检查:内部类行数的长度、可执行语句数量限制、文件长度、行的长度、方法代码行数的限制…

3.2 P3c

  1. 并发代码: 是否设置线程名检查、创建线程是否使用线程池检查…
  2. 集合代码: 集合移除元素remove方法检查,subList方法使用检查
  3. 命名检查
  4. 常量检查: Long类型定义是检查是否使用L替代了l
  5. oop检查: 检查是否使用了启用的类或者方法、
  6. 流程控制语句检查
  7. 异常检查:当抛异常时是否回滚
  8. 注释检查
  9. 其他一些: 避免使用apache beanutils拷贝属性
    见附录可查看具体的检查项。

4.使用方式

4.1 独立使用

4.1.1 Checkstyle

 java -jar checkstyle-8.24-all.jar -c 规则文件 -f xml -o 结果输出文件  要检查的项目目录(指定src/main/java目录,只检测逻辑源码,不检测单测代码)
  • -c 制定规则文件
  • -f 输出结果格式 默认为普通文本
  • -o 指定输出文件目录

输出Xml文件中的最小单元

<file name="D:\soft\gitcode\sqms_artifact\src\main\java\com\wizard\artifact\
authorization\annotation\AuthorizeAllRole.java">
	<error line="8" severity="warning" message="Javadoc的第一句缺少一个结束时期。" source="com.puppycrawl.tools.checkstyle.checks.javadoc.SummaryJavadocCheck"/>
	<error line="18" column="1" severity="warning" message="行内含有制表符 tab 。" source="com.puppycrawl.tools.checkstyle.checks.whitespace.FileTabCharacterCheck"/>
	<error line="19" severity="warning" message="Javadoc的第一句缺少一个结束时期。" source="com.puppycrawl.tools.checkstyle.checks.javadoc.SummaryJavadocCheck"/>
</file>

4.1.2 P3c

 java -cp p3c-pmd.jar net.sourceforge.pmd.PMD -d /usr/src -R rule/ali-comment.xml -f text
  • -d 源码文件
  • -R 指定规则,多个规则以分号分开
  • -f 输出报告结果格式 text,html,xml
<file name="D:\soft\gitcode\sqms_artifact\src\main\java\com\wizard\artifact\common\EnumFormat.java">
<violation beginline="10"	endline="39"	begincolumn="52"	endcolumn="1"			 rule="EnumConstantsMustHaveCommentRule"	ruleset="AlibabaJavaComments" package="com.wizard.artifact.common" class="EnumFormat" priority="2">
			枚举【EnumFormat】的字段缺少注释信息
	</violation>
</file>

4.2 Maven插件执行

4.2.1 Checkstyle

 mvn checkstyle:checkstyle 

检查工程是否满足checkstyle的检查,如果没有满足,检查不会失败,检查结果xml位于target目录下。

mvn checkstyle:check

检查工程是否满足checkstyle的检查,如果没有满足,检查会失败,检查结果xml位于target目录下。

输出xml文件中的最小单元:

<file	name="D:\soft\gitcode\sqms_artifact\src\main\java\com\wizard
\artifact\vulnerability\service\CicdVulnerabilityDetailService.java">
	<error line="41" column="88" severity="error" message="&apos;{&apos; 前应有空格。" source="com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAroundCheck"/>
</file>

4.2.2 P3c

mvn pmd:pmd

检查工程是否满足p3c的检查,如果没有满足,检查不会失败,检查结果pmd.xml位于target目录下。

mvn pmd:check

检查工程是否满足p3c的检查,如果没有满足,检查会失败,检查结果pmd.xml位于target目录下。

输出Xml文件中的最小单元

<file	name="D:\soft\gitcode\sqms_artifact\src\main\java\com\wizard
\artifact\common\EnumFormat.java">
<violation	beginline="10"	endline="39"	begincolumn="52"	endcolumn="1" rule="EnumConstantsMustHaveCommentRule"	ruleset="AlibabaJavaComments" package="com.wizard.artifact.common" class="EnumFormat" priority="2">
			枚举【EnumFormat】的字段缺少注释信息
		</violation>
</file>

5.忽略检查

5.1 checkstyle

  1. 单独使用时指定只执行的检查的文件
  2. 在pom中对应的插件配置要忽略的文件
  3. mvn clean package -Dcheckstyle.skip=true 在打包的时候忽略checkstyle检查

5.2 p3c

  1. 在pom对用的插件中配置要忽略的文件excludes>
  2. 在类上添加注解 @SuppressWarnings(“PMD”)
  3. mvn clean package -Dpmd.skip=true 在打包的时候忽略p3c检查

6. maven项目pom配置checkstyle支持代码检查

6.1 pom配置plugin

<build>
  <plugins>
        <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-checkstyle-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <!-- 如果没有配置 使用默认的sun_check.xml文件   -->
                    <configLocation>src/main/resources/checkstyle.xml</configLocation>
                    <encoding>UTF-8</encoding>
                    <!-- consoleOutput  false: 不输出到控制台 true 输出到控制台  failsOnError: true是 此参数才有作用    -->
                    <consoleOutput>false</consoleOutput>
                    <!--  failsOnError : true: 输出原始的错误,有乱码  false: 输出解析后的错误,没有乱码  -->
                    <failsOnError>false</failsOnError>
                    <linkXRef>true</linkXRef>
                </configuration>
                <executions>
                    <execution>
                        <id>validate</id>
                        <phase>validate</phase>
                        <goals>
                            <goal>check</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
  </plugins>

</build>

6.2 配置检查规则

存放文件checkstyle.xml于 /src/main/resources/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">
 
    <!-- 检查文件是否以一个空行结束 -->
    <module name="NewlineAtEndOfFile"/>
 
    <!-- 文件长度不超过1500行 -->
    <module name="FileLength">
        <property name="max" value="1500"/>
     </module>
 
    <!-- 每个java文件一个语法树 -->
    <module name="TreeWalker">
        <!-- import检查-->
        <!-- 检查是否从非法的包中导入了类 -->
        <module name="IllegalImport"/>
        <!-- 检查是否导入了多余的包 -->
        <module name="RedundantImport"/>
        <!-- 没用的import检查,比如:1.没有被用到2.重复的3.import java.lang的4.import 与该类在同一个package的 -->
        <module name="UnusedImports" />
 
        <!-- 注释检查 -->
        <!-- 检查构造函数的javadoc -->
        <module name="JavadocType">
            <property name="allowUnknownTags" value="true"/>
            <message key="javadoc.missing" value="类注释:缺少Javadoc注释。"/>
        </module>
 
        <!-- 命名检查 -->
        <!-- 局部的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"/>
        <!-- 检查long型定义是否有大写的“L” -->
        <module name="UpperEll"/>
 
        <!-- 长度检查 -->
        <!-- 每行不超过140个字符 -->
        <module name="LineLength">
            <property name="max" value="140" />
        </module>
        <!-- 方法不超过50行 -->
        <module name="MethodLength">
            <property name="tokens" value="METHOD_DEF" />
            <property name="max" value="50" />
        </module>
        <!-- 方法的参数个数不超过6个。 并且不对构造方法进行检查-->
        <module name="ParameterNumber">
            <property name="max" value="6" />
            <property name="ignoreOverriddenMethods" value="true"/>
            <property name="tokens" value="METHOD_DEF" />
        </module>
 
        <!-- 空格检查-->
        <!-- 方法名后跟左圆括号"(" -->
        <module name="MethodParamPad" />
        <!-- 在类型转换时,不允许左圆括号右边有空格,也不允许与右圆括号左边有空格 -->
        <module name="TypecastParenPad" />
        <!-- 检查在某个特定关键字之后应保留空格 -->
        <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="EmptyStatement"/>
        <!-- 检查在重写了equals方法后是否重写了hashCode方法 -->
        <module name="EqualsHashCode"/>
        <!-- 检查局部变量或参数是否隐藏了类中的变量 -->
        <module name="HiddenField">
            <property name="tokens" value="VARIABLE_DEF"/>
        </module>
        <!-- 检查子表达式中是否有赋值操作 -->
        <module name="InnerAssignment"/>
        <!-- 检查switch语句是否有default -->
        <module name="MissingSwitchDefault"/>
        <!-- 检查是否有过度复杂的布尔表达式 -->
        <module name="SimplifyBooleanExpression"/>
        <!-- 检查是否有过于复杂的布尔返回代码段 -->
        <module name="SimplifyBooleanReturn"/>
 
        <!-- 类设计检查 -->
        <!-- 检查类是否为扩展设计l -->
        <!-- 检查只有private构造函数的类是否声明为final -->
        <module name="FinalClass"/>
        <!-- 检查接口是否仅定义类型 -->
        <module name="InterfaceIsType"/>
        <!-- 检查类成员的可见度 检查类成员的可见性。只有static final 成员是public的 
        除非在本检查的protectedAllowed和packagedAllowed属性中进行了设置-->
        <module name="VisibilityModifier">
            <property name="packageAllowed" value="true"/>
            <property name="protectedAllowed" value="true"/>
        </module>
 
        <!-- 语法 -->
        <!-- String的比较不能用!= 和 == -->
        <module name="StringLiteralEquality"/>
        <!-- 限制for循环最多嵌套2层 -->
        <module name="NestedForDepth">
            <property name="max" value="2"/>
        </module>
        <!-- if最多嵌套3层 -->
        <module name="NestedIfDepth">
            <property name="max" value="3"/>
        </module>
        <!-- 检查未被注释的main方法,排除以Appllication结尾命名的类 -->
        <module name="UncommentedMain">
            <property name="excludedClasses" value=".*[Application,Test]$"/>
        </module>
        <!-- 禁止使用System.out.println -->
        <module name="Regexp">
            <property name="format" value="System\.out\.println"/>
            <property name="illegalPattern" value="true"/>
        </module>
        <!-- throw后不能使用1个以上空格 -->
        <module name="Regexp">
            <property name="format" value="throw\s{2,}\w"/>
            <property name="illegalPattern" value="true"/>
        </module>
        <!-- return后不能使用1个以上空格 -->
        <module name="Regexp">
            <property name="format" value="return\s{2,}\w"/>
            <property name="illegalPattern" value="true"/>
        </module>
        <!-- return个数 3个-->
        <module name="ReturnCount">
            <property name="max" value="7"/>
        </module>
        <!--try catch 异常处理数量 3-->
        <module name="NestedTryDepth ">
            <property name="max" value="3"/>
        </module>
        <!-- clone方法必须调用了super.clone() -->
        <module name="SuperClone" />
        <!-- finalize 必须调用了super.finalize() -->
        <module name="SuperFinalize" />
 
 
    </module>
</module>

附录

P3C具体的检查项

  1. 并发检查,必须回收自定义的ThreadLocal变量,尤其在线程池场景下,线程经常会被复用,如果不清理自定义的ThreadLoacal变量,可能会影响后续业务逻辑和造成内存泄漏等问题。
  2. 并发检查,有意义的线程名称有助于跟踪错误信息,因此在创建线程或线程池时指定名称。
  3. 并发检查,不允许直接创建线程,应该有线程池提供线程
  4. 并发检查,线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式。
  5. 并发检查,SimpleDateFormat是线程不安全的类,一般不要定义为static变量,如果定义为static,必须加锁,或者使用DateUtils工具类。
  6. 并发检查,多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其他任务便会自动终止运行,如果在处理定时任务时使用ScheduledExecutorService则没有这个问题。
  7. 并发检查,使用CountDownLatch进行异步转同步操作,每个线程退出前必须调用countDown方法,线程执行代码注意catch异常,确保countDown方法被执行到,避免主线程无法执行至await方法,直到超时才返回结果。
  8. 集合检查,ArrayList的subList结果不可强转为ArrayList,否则会抛ClassCastException异常,即java.util.RandomAccessSubList cannot be cast to java.util.ArrayList。
  9. 集合检查,在subList场景中,高度注意对原集合元素的增加或删除,均会导致子列表的遍历、增加、删除产生ConcurrentModiificationException异常。
  10. 集合检查,使用集合转数组的方法,必须使用集合的toArray(T[] array),传入的是类型完全一致,长度为0的空数组。
  11. 集合检查,使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportedOperationException异常。
  12. 集合检查,不要在foreach循环里进行元素的remove/add操作。Remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁。
  13. 集合检查,集合初始化时,指定集合初始化大小。
  14. 命名检查,代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。
  15. 命名检查,代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。
  16. 命名检查,类名使用UpperCamelCase风格,但以下情形例外:DO/BO/DTO/VO/AO/PO/UID等。
  17. 命名检查,方法名,参数名,成员变量,局部变量都统一使用lowerCamelCase风格,必须遵从驼峰方式。
  18. 命名检查,常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。
  19. 命名检查,抽象类命名使用Abstract或Base开头;异常类命名使用Exception结尾;测试类命名以它要测试的类的名称开始,以Test结尾。
  20. 命名检查,类型与中括号紧挨相连来表示数组。
  21. 命名检查,POJO类中布尔类型变量都不要加is前缀,否则部分框架解析会引起序列化错误。
  22. 命名检查,包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。
  23. 命名检查,接口和实现类的命名有两套规则:1.对与service和Dao类,基于SOA的理念,暴露出来的服务一定是接口,内部的实现类用Impl的后缀与接口区别。2.如果是形容能力的接口名称,取对应的形容词为接口名。(通常是-able的形容词)。
  24. 常量检查,不允许任何魔法值(即未经预先定义的常量)直接出现在代码中。
  25. 常量检查,在long或者Long赋值时,数值后使用大写的L,不能是小写的l,小写容易跟数字1混淆,造成误解。
  26. OOP检查,不能使用过时的类和方法
  27. OOP检查,object的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用equals。
  28. OOP检查,所有整型包装类对象之间值的比较,全部使用equals方法比较。
  29. OOP检查,关于基本数据类型与包装数据类型的使用标准如下:1.所有的POJO类属性必须使用包装数据类型 2. RPC方法的返回值和参数必须使用包装数据类型 3. 所有的局部使用基本数据类型。
  30. OOP检查,定义DO/DTO/VO等POJO类时,不要设定任何属性默认值。
  31. OOP检查,POJO类必须重写toString方法,
  32. OOP检查,循环体内,字符串的连接方式,使用StringBuilder的append方法进行扩展。
  33. 控制语句检查,在一个switch块内,每个case要么通过continue/break/return等来终止,要么注释说明程序将继续执行到哪一个case为止,在一个switch块内,都必须包含一个default语句并且放在最后,即使它什么代码也没有
  34. 流程句检查,在if/else/for/while/fo语句中必须使用大括号。
  35. 控制语句检查,除常用方法(getXxx/isXxx)等外,不要在条件判断中执行其他复杂的语句,将复杂逻辑判断的结果赋值给一个有意义的布尔变量名,以提高可读性。
  36. 控制语句检查,避免采用取反逻辑运算符。
  37. 异常检查,有try块放到了事务代码中,catch异常后,如果需要回滚事务,一定要注意手动回滚事务。
  38. 异常检查,不要在finally块中使用return
  39. 异常检查,防止NPE,是程序员的基本修养,注意NPE产生的场景 1. 返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生NPE 2. 数据库的查询结果可能为Null,3. 集合里的元素即使isNotEmpty,取出来的数据元素也可能为Null 4.远程调用返回对象时,一律要求进行空指针判断,防止NPE 5. 对于session中获取的数据,建议进行NPE检查,避免空指针 6. 级联调用obj.getA().getB().getC(),一连串调用,易产生NPE
  40. 注释检查,类,类属性,类方法的注释必须使用JAVADOC规范,使用/内容/格式,不得使用//xxx 方式
  41. 注释检查,所有的抽象方法(包括接口中的方法)必须使用javadoc注释、除了返回值、参数、异常说明外,还必须指出该方法做什么事情,实现什么功能。
  42. 注释检查,所有的类都必须添加创建者和创建者日期
  43. 注释检查,方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释使用/**/注释,注意与对齐。
  44. 注释检查,所有的枚举类型字段都必须要有注释,说明每个数据项的用途
  45. 其他检查,及时清理不再使用的代码段或配置信息。
  46. 其他检查,避免使用apache beanUitls复制属性
  47. 其他检查,在使用正则表达式时,利用好其预编译功能,可以有效加快正则匹配速度。
  48. 其他检查,后台输送给页面的变量必须加$!{var}-----中间的感叹号
  49. 其他检查,注意Math.random()这个方法返回是double类型,注意取值的范围0<= x <1(能够取到零值,注意除零异常),如果想获取整数类型的随机数,不要将X放大10的若干倍然后去整,直接使用Random对象的nexInt或者nextLong方法。
  50. 其他检查,获取当前毫秒数system.currentTimeMillis();而不是new Date().getTime()
  51. 其他检查,日期格式化时,传入pattern中表示年份统一使用小写的y。
  52. 其他检查,单个方法的总行数不应超过80行。除注释之外的方法签名、左右大括号、方法内代码、空行、回车及任何不可见字符的总行数不超过80行。

Checkstyle具体的检查项

  1. 检查文件是否以空行结束
  2. 文件长度不超过1500行(可配置)
  3. 检查是否导入多余的包
  4. 检查是否从非法的包中导入了类
  5. 没有用到的import的检查:没有用到 、重复的、import java.lang的、import与该类在同一个package的
  6. 注释检查:检查构造函数的javadoc
  7. 局部的final变量,包括catch中的参数检查
  8. 局部的非final型的变量,包括catch中的参数检查
  9. 包名的检查(只允许小写字母),默认1+(.[a-Za-z_][a-Za-z_0-9_])$
  10. 仅仅是static型的变量(不包括static final型)的检查
  11. Class或Interface名检查,默认2[a-zA-Z0-9]*$
  12. 非static型变量的命名检查
  13. 方法名的检查
  14. 方法的参数名
  15. 常量名的检查(只允许大写),默认3[A-Z0-9](_[A-Z0-9]+)$
  16. 检查数组类型定义的样式
  17. 检查Long类型定义是否有大写的L
  18. 长度检查,每行不超过140个字符(可配置)
  19. 方法行数不超过50行(可配置)
  20. 方法的参数个数不超过6个,并且不对构造方法进行检查
  21. 空格检查,方法名后跟左圆括号
  22. 空格检查,在类型转换时,不允许左圆括号右边有空格,也不允许与右圆括号左边也有空格
  23. 空格检查,检查某个特定关键字之后应保留空格
  24. 空格检查,检查在某个特定关键字之前保留空格
  25. 空格检查,操作符换行策略检查
  26. 空格检查,圆括号空白
  27. 空格检查,检查分隔符是否在空白之后
  28. 空格检查,检查分隔符周围是否有空白
  29. 修饰符检查,检查修饰符的顺序是否遵照java语言规范,默认Public,protected,private,abstract,static,final,transient,volatile,synchronized,native,strictfp
  30. 检查接口和annotation中是否有多余修饰符,如接口方法不必使用Public
  31. 代码块检查,检查是否有嵌套代码块
  32. 代码块检查,检查是否有空代码块
  33. 代码块检查,检查左大括号位置
  34. 代码块检查,检查代码块是否缺失{}
  35. 代码块检查,检查右大括号位置
  36. 代码检查,检查空的代码段
  37. 代码检查,检查在重写了equals方法后是否重写了hashcode方法
  38. 代码检查,检查局部变量或参数是否隐藏了类中的变量
  39. 代码检查,检查子表达式中是否有赋值操作
  40. 代码检查,检查switch语句是否有default
  41. 代码检查,检查是否有过度复杂的布尔表达式
  42. 代码检查,检查是否有过于复杂的布尔返回代码段
  43. 类设计检查,检查只有private构造函数的类是否声明为final
  44. 类设计检查,检查接口是否仅定义类型
  45. 类设计检查,检查类成员的可见度,检查类成员的可见性。只有static final 成员是public的。
  46. 语法检查,string的比较不能用!=和==
  47. 语法检查,限制for循环最多嵌套2层(可配置)
  48. 语法检查,if最多3层嵌套(可配置)
  49. 语法检查,禁止使用system.out.println
  50. 语法检查,throw后不能使用1个以上空格
  51. 语法检查,return后不能使用1个以上空格
  52. 语法检查,方法中return个数限制3个(可配置)
  53. 语法检查,try catch异常处理数量限制3个(可配置)
  54. 语法检查,clone方法必须调用了super.clone()
  55. 语法检查,finalize必须调用了super.finalize()

  1. a-z ↩︎

  2. A-Z ↩︎

  3. A-Z ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值