vieyahn2017 / javaway

java on the way
5 stars 3 forks source link

2.28 Java代码规范和工具简单介绍 #121

Closed vieyahn2017 closed 5 years ago

vieyahn2017 commented 5 years ago

Java静态检测工具/Java代码规范和质量检查简单介绍(转)

https://www.cnblogs.com/EasonJim/p/7685724.html

静态检查:

静态测试包括代码检查、静态结构分析、代码质量度量等。它可以由人工进行,充分发挥人的逻辑思维优势,也可以借助软件工具自动进行。代码检查代码检查包括代码走查、桌面检查、代码审查等,主要检查代码和设计的一致性, 代码对标准的遵循、可读性,代码的逻辑表达的正确性,代码结构的合理性等方面;可以发现违背程序编写标准的问题,程序中不安全、不明确和模糊的部分,找出程序中不可移植部分、违背程序编程风格的问题,包括变量检查、命名和类型审查、程序逻辑审查、程序语法检查和程序结构检查等内容。”。看了一系列的静态代码扫描或者叫静态代码分析工具后,总结对工具的看法:静态代码扫描工具,和编译器的某些功能其实是很相似的,他们也需要词法分析,语法分析,语意分析...但和编译器不一样的是他们可以自定义各种各样的复杂的规则去对代码进行分析。

vieyahn2017 commented 5 years ago

静态检测工具:

Checkstyle

1)定义: Checkstyle是一款检查Java程序源代码样式的工具。 2)特点: 1)它可以有效的帮助我们检视代码以便更好的遵循代码编写标准,特别适用于小组开发时彼此间的样式规范和统一。 2)Checkstyle提供了高可配置性,以便适用于各种代码规范,所以除了使用它提供的几种常见标准之外,你也可以定制自己的标准。 3)Checkstyle提供了支持大多数常见IDE的插件,大部分插件中就含有最新的Checkstyle,就不用费心再部署一份了。 4)Checkstyle可以检查代码的很多方面,从传统观点看,它主要是用来检查代码层面的,自从第三版以后,它的内部架构作了重大改变,很多其它意图的检测加了进来,现在Checkstyle可以检查像类设计的问题,重复代码,如锁的双重检查的bug模式。 3)CheckStyle的主要流程是: 1)对Java文件进行词法语法分析,生成语法树。 2)载入配置文件(checkstyle-metadata.xml以及自定义的配置文件)register check事件。 3)按照深度优先遍历对语法树进行解析,按照注册的事件,在到达某些节点( AST ) 时进行style检查(AST,A child-Sibling Tree,是语法树中的某个节点,其类型在TokenTypes类中定义。) 4)我们所说的自定义Style的检查,就是在第二步设定的。这里牵涉到一个叫com.puppycrawl.tools.checkstyle.api.Check 的类,我们通常需要重载其中的两个函数: public int[] getDefaultTokens()和public void visitToken(DetailAST ast). 这两个函数的含义为,在遍历语法树的过程中,每当到达getDefaultTokens函数所返回的AST类型,程序就进入visitToken进行具体的检查和分析,即,真正的分析检查过程是在visitToken中实现的。

FindBugs

1)FindBugs是一个开源的静态代码分析工具,基于LGPL开源协议,无需运行就能对代码进行分析的工具。不注重style及format,注重检测真正的bug及潜在的性能问题 ,尤其注意了尽可能抑制误检测(false positives)的发生。以bytecode(.class、.jar)为对象进行检查。除了单独动作,还可以用作Eclipse 的plug-in,以及嵌入Ant作为task之一 进行利用。 2)findbugs自带检测器的介绍: findbugs自带60余种Bad practice,80余种Correntness,1种Internationalization,12种Malicious code vulnerability,27种Multithreaded correntness,23种Performance,43种Dodgy。 3)Findbugs的一些特点: 1)FindBugs主要着眼于寻找代码中的缺陷,这就与其他类似工具有些区别了,直接操作类文件(class文件)而不是源代码。 2)FindBugs可以通过命令行、各种构建工具(如Ant、Maven等)、独立的Swing GUI或是以Eclipse和NetBeans IDE插件的方式来运行。 3)FindBugs输出结果既可以是XML的,也可以是文本形式的。 4)开发者可以通过多种方式来使用FindBugs,最常见的是在新编写模块的代码分析以及对现有代码进行更大范围的分析。 5)不注重style及format,注重检测真正的bug及潜在的性能问题,尤其注意了尽可能抑制误检测(false positives)的发生。 4)FindBugs可检测的bug pattern举例:检测java programing中容易陷入的bug pattern,equals() 实现时的一般规约违反Null pointer的参照 ,Method的返回值的check遗漏 ,初始化前field的访问,Multi-thread的正确性, 同期化处理的矛盾, 无条件的wait(), Code的脆弱性 ,可以变更的静态object ,内部数列参照的return等

PMD

1)PMD是一个代码检查工具,它用于分析Java源代码,找出潜在的问题: 1)潜在的bug:空的try/catch/finally/switch语句 2)未使用的代码:未使用的局部变量、参数、私有方法等 3)可选的代码:String/StringBuffer的滥用 4)复杂的表达式:不必须的if语句、可以使用while循环完成的for循环 5)重复的代码:拷贝/粘贴代码意味着拷贝/粘贴bugs 2)PMD特点: 1)与其他分析工具不同的是,PMD通过静态分析获知代码错误。也就是说,在不运行Java程序的情况下报告错误。 2)PMD附带了许多可以直接使用的规则,利用这些规则可以找出Java源程序的许多问题 3)用户还可以自己定义规则,检查Java代码是否符合某些特定的编码规范。 3)同时,PMD已经与JDeveloper、Eclipse、jEdit、JBuilder、BlueJ、CodeGuide、NetBeans、Sun JavaStudio Enterprise/Creator、IntelliJ IDEA、TextPad、Maven、Ant、Gel、JCreator以及Emacs集成在一起。 4)PMD规则是可以定制的: 可用的规则并不仅限于内置规则。您可以添加新规则:可以通过编写Java代码并重新编译PDM,或者更简单些,编写XPath表达式,它会针对每个Java类的抽象语法树进行处理。 5)只使用PDM内置规则,PMD也可以找到你代码中的一些真正问题。某些问题可能很小,但有些问题则可能很大。PMD不可能找到每个bug,你仍然需要做单元测试和接受测试,在查找已知bug时,即使是PMD也无法替代一个好的调试器。 但是,PMD确实可以帮助你发现未知的问题。

vieyahn2017 commented 5 years ago

静态检测工具:

Hammurapi

1)定义: Hammurapi它是一个开源的代码审查/评审(review)工具。它可以帮助改进Java代码的质量。它可以基于一套设计规范来分析代码库。当它碰到违反规范的地方,会在报告中标识。就像Checkstyle一样,它与Ant无缝集成并且由基于XML配置文件来驱动。 2)特点: 1)Hammurapi是用来强制代码设计规范的。 2)Hammurapi是一个遵循设计的工具,提供了自动而且一致的方式来实现设计规范,因此使代码评审更加有效而轻松。 3)Hammurapi如何工作:Hammurapi这样的代码分析工具都带有语言分析器。语言分析器是一种输入语言代码并输出抽象语法树的工具。这个树上的节点代表语言标识。例如,考虑一下简单的算术表达式:3+4. 语言分析器会解析他成为一个如图5所示的语法树。在这个树中,节点+代表操作符标识。节点3和4是操作数标识Hammurapi使用ANTLR(另一个语言识别工具)作为语言分析器。然而ANTLR API是相当底层的。为改善可用性,Hammurapi使用另一个API,基于ANTLR 的JSEL(Java源程序工程类库),来访问抽象语法树。 一旦树构建完成,一种树遍历算法就被用来访问树中每一个节点。每次访问到一个节点,一种回调机制(Visitor模式)被用来提示相应的检查器。在这些回调方法中,检查器收集相关的信息来确定是否有违反规范的地方存在。  

Lint4j

1)定义:Lint4J是一个针对Java的源代码分析工具,它可以对Java源码和字节码进行静态分析,判断其中是否存在死锁、性能问题或者伸缩性问题。它可以集成到任何IDE种或构建系统 2)特点: 1)检测代码语法规则 2)潜在的bug 3)检测编码模式对代码可读性及大小的影响 4)检测是否违反EJB规范

Sonar

1)定义:代码质量管理工具Sonar提供了设计与架构度量。Sonar 2.0引入了针对Java应用的设计分析、架构与面向对象的度量,Sonar 2.1可以检测到未使用的方法以及对不建议使用方法的调用。是一个集成了CheckStyle,PMD,Findbugs的代码校验规则 ,重复代码发现,代码测试覆盖率, 代码注释率,及所有的检测率变化追踪的完美代码质量检查工具。它包含了代码质量检测的七个方面 2)特点: 1)代码覆盖:通过单元测试,将会显示哪行代码被选中。 2)改善编码规则。 3)搜寻编码规则:按照名字,插件,激活级别和类别进行查询。 4)项目搜寻:按照项目的名字进行查询。 5)对比数据:比较同一张表中的任何测量的趋势。 6)单元测试 3)Sonar2.1: Sonar还基于Squid引入了一个全新的规则引擎、Sonar解析器既可以处理源代码,也可以处理字节码,解析器带有内建的规则,可以检测未使用的私有与保护方法以及客户端对不建议使用的方法的调用。Squid通过分析应用源代码、Java API和外部程序库的字节码来决定哪些方法、类和属性是不建议使用的。 Sonar 2.1的新特性: 1)一个全新的“Libraries”页面,显示了项目中所有的程序库和依赖,该特性要求使用Maven来构建项目。一旦在Sonar站点的主页上选择了一个项目,该服务就会以可视化的树形结构展示出项目依赖。此外,还有一个可选的动态过滤器,可以根据名称过滤程序库以便在应用的依赖间导航。 2)用于搜索程序库使用情况的“Dependencies”页面。比如说,可以搜索到使用了第三方框架如Commons Logging 1.1的所有项目。 3)可以使用各种插件扩展Sonar的功能。现在有一个全新的“System Info”页面显示了系统属性、已装插件和Java虚拟机内存统计信息。该页面还给出了关于Sonar配置和数据库统计的详细信息。 4)一个用于管理已装插件和系统信息的管理控制台。最新版的Sonar为这些插件引入了一个测试框架和一个客户化的Maven生命周期管理工具。它还带有一个用于集成项目事件的Web Service并在项目的size widget中增加了一个新的度量模块。

JDepend

1)JDepend一个开放源代码的可以用来评价Java程序质量的优秀工具,它遍历Java class的文件目录,以Java包(package)为单位,为每一个包/类自动生成 包的依赖程度,稳定性,可靠度等的评价报告,根据这些报告,我们可以得到包或类之间的依赖关系,并分析出包的稳定程度,抽象程度,是否存在循环依耐关系等 。可以根据JDepend给出的报告数据,分析出我们的包是否是可靠的,稳定的,健壮的包,是否符合面向对象的设计原则。 2)特点: 1)评价设计质量 2)翻转依赖性 3)支持并行开发和极限编程 4)独立的发布模块 5)识别package的循环依赖 3)Depend生成的Java包的质量评价报告主要包括: 1)Number of Classes and Interfaces:实现类与抽象接口的数目 2)Abstractness (A):包的抽象度。指一个包内包含的抽象类或接口占整个包中的类的比重。 3)Afferent Couplings (Ca):向心耦合。依赖该包(包含的类)的外部包(类)的数目(i.e. incoming dependencies),该数值越大,说明该包的担当的职责越大,也就越稳定。 4)Efferent Couplings (Ce):离心耦合。被该包依赖的外部包的数目(i.e. outgoing dependencies),该数值越大, 说明该包越不独立(因为依赖了别的包),也越不稳定。 5)Instability (I):衡量一个包的不稳定程度。I=Ce/(Ce+Ca)。它的值处于[0,1]之间。I=0时说明包是最稳定的,反之I=1则说明包极不稳定。 6)Distance from the Main Sequence (D): 该指标主要用来评价包的抽象程度与稳定程度的平衡关系,它可以用二维直线图 A + I = 1 来表示。 7)Package Dependency Cycles:包的循环依赖度。

IBM Checking Tool for Bugs Errors and Mistakes(简称BEAM)

1) 定义:是 IBM 开发的一个静态分析工具,可以用于分析并查找出 C, C++ 和 Java代码中的一些不容易发现的潜在错误,从而达到提高代码质量的目的。同动态分析工具和其它静态分析工具相比,它拥有一些可贵的特性。 2)特点: 1)对代码进行语法扫描,通过算法对代码进行检查分析 2)和一些 bug 模式进行比较,最终标明问题区域,输出分析结果 3)使用了额外的定理证明(theorem proving)技术来判断一个潜在的错误是否是真正的错误,从而减轻了程序员判断错误真伪所需的工作量

LDRA Testbed

1)定义:LDRA Testbed为应用软件的确认和验证提供强大的源代码测试和分析功能,是独特的质量控制工具。 它有助于提高计算机软件必需的可靠性,健壮性和尽可能的零缺陷,它的使用带来时间、成本和效率上真实的节省,这些都是无法衡量其价值的。它是强大和完整的集成工具包,使先进的软件分析技术应用在开发生命周期的关键阶段。 2)LDRA Testbed提供强大的分析功能,用于两个主要的测试领域,静态分析和动态分析。 1)静态分析: 分析代码,并且提供对代码结构的理解。 2)动态分析: 利用源代码的插装版本,使用测试数据执行,在运行时发现软件缺陷 3) 使用LDRA testbed 的好处软件开发和测试过程的成本效率分析工具单元、集成和系统测试的理想工具贯穿于软件开发的整个生命周期LDRA Testbed应用于许多不同的领域过程改进软件测试软件维护 LDRA Testbed的优点: 改进软件质量 定位软件缺陷 强制执行工业标准 减少维护费用40%以上 减少开发和测试成本75%以上 通过自动化过程提高员工动力

Yasca

1) 定义:Yasca是一个开源静态代码分析工具插件框架, 集成流行的多语言静态分析工具如findbugs/pmd/jlint/rats/cppcheck,由于插件本身多样故可支持java c++等语言静态分析.Yasca是一个用来寻找安全漏洞,在程序的源代码中检测代码质量、性能以及一致性的软件。它集成了其他开源项目,其中包括FindBugs PMD ,JLint , Cppcheck ,并扫描某些文件类型,以及自定义扫描书面的Yasca 这是一个命令行工具,与报告中生成的HTML , CSV格式, XML,SQLite ,和其他格式。

参考:

http://tianya23.blog.51cto.com/1081650/415146(以上内容转自此篇文章

posted @ 2017-10-18 11:36 EasonJim 阅读(...) 评论(...) 编辑 收藏

vieyahn2017 commented 5 years ago

checkstyle_ruleset_minimal.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">

**************************************************************************************************************-->
<module name="Checker">
    <!--规则1.1 源文件编码格式(包括注释)必须是UTF-8,ASCII水平空格字符(0x20,即空格)是唯一允许出现的空白字符,制表符不用于缩进-->
    <property name="charset" value="UTF-8"/>
    <property name="fileExtensions" value="java"/>
    <!-- 使用 CHECKSTYLE:OFF and CHECKSTYLE:ON注释内容关闭或者开启某个检查 -->
    <module name="SuppressWithPlainTextCommentFilter">
        <property name="offCommentFormat" value="CHECKSTYLE\:OFF\:\s*(\w+)"/>
        <property name="onCommentFormat" value="CHECKSTYLE\:ON\:\s*(\w+)"/>
        <property name="checkFormat" value="$1"/>
    </module> 

    <!-- 规则1.3 避免文件过长,不超过2000行(非空非注释行) -->
    <module name="FileLength">
        <property name="max" value="2000"/>
    </module>
    <!-- 规则3.3 使用空格进行缩进,每次缩进4个空格: 不允许用Tab -->
    <module name="FileTabCharacter"/>
    <!-- 规则1.2 版权检查-->
    <module name="RegexpSingleline">
        <property name="format" value="^(//| \*) Copyright \(c\) XXXX Technologies Co., Ltd. [\d]{4}(\-[\d]{4})?\. All rights reserved\.$"/>
        <property name="minimum" value="1"/>
        <property name="maximum" value="1"/>
        <property name="message" value="编程规范-规则1.2: 版权缺失或者格式不正确"/>
        <property name="severity" value="error"/>
    </module>
    <!-- 规则2.5 注释符与注释内容间要有1空格;右置注释与前面代码至少1空-->
    <!-- 检查类似:1)/*XXXX 左边无空格注释 2) //XXXX 左边无空格注释 -->
    <module name="RegexpSingleline">
        <property name="format" value="[^:]//[^\s]"/>
        <property name="message" value="编程规范-规则2.5: 请添加空格(单行注释符与注释内容间以空格分割)"/>
    </module>
    <!-- 检查类似:/*XXXX*/ 右边无空格注释-->
    <module name="RegexpSingleline">
        <property name="format" value="(\*)+[\u4E00-\u9FA5A-Za-z0-9_]"/>
        <property name="message" value="编程规范-规则2.5: 请添加空格(单行注释符与注释内容间以空格分割)"/>
    </module> 
    <module name="RegexpSingleline">
        <property name="format" value="[\u4E00-\u9FA5A-Za-z0-9_]((\*)+)/"/>
        <property name="message" value="编程规范-规则2.5: 请添加空格(单行注释符与注释内容间以空格分割)"/>
    </module>
    <!--规则2.4 注释符与注释内容间要有1空格;右置注释与前面代码至少1空格-->
    <module name="RegexpSingleline">
        <property name="format" value=".*;//"/>
        <property name="message" value="编程规范-规则2.5:请添加空格(分号和单行注释符间以空格分割)"/>
    </module>
    <!-- 建议4.3 基本类型优于包装类型,注意合理使用包装类型 (包装类型只能用于泛型、集合中元素、反射)-->
    <module name="RegexpSingleline">
        <property name="format" value="\s+(Byte|Short|Integer|Long|Float|Double|Character|Boolean)\s+"/>
        <property name="message" value="编程规范-建议4.3: 请使用基本类型"/>
    </module>
    <!-- 规则7.7 日志应分等级,对info及以下,使用条件形式或者使用占位符的方式 -->
    <module name="RegexpSingleline">
        <property name="format" value="(LOG|LOGGER|log|logger)\.(fatal|error|warn|info|debug)\((([^&quot;].+)|&quot;.+&quot;[^,])\s*(.*)\+"/>
        <property name="message" value="编程规范-规则7.7 : 日志应分等级,对info及以下,使用条件形式或者使用占位符的方式"/>
    </module>
    <!-- 规则7.8 非仅限于中文区销售产品禁止用中文打印日志 -->
    <module name="RegexpSingleline">
        <property name="format" value="(LOG|LOGGER|log|logger)\.(fatal|error|warn|info|debug).+[\u4e00-\u9fa5]+"/>
        <property name="message" value="编程规范-规则7.8: 禁止用中文打印日志"/>
    </module>
    <!-- <module name="RegexpSingleline">
        <property name="format" value="^\s*return null;\s*$"/>
        <property name="message" value="禁止返回null! 1)编程规范-建议8.6.3: 集合请返回Collections.emptyXXX() 2)编程规范-建议8.6.2: 其他请使用JAVA 8 Optional特性代替"/>
    </module> -->
    <module name="RegexpSingleline">
        <property name="format" value="\s+$"/>
        <property name="message" value="编程规范-建议3.5 行末或空行不能有空格, 请去除多余空格"/>
    </module>
    <!-- 
    HashMap/HashSet/LinkedHashSet:已知元素个数填实际个数,未知填默认值16; 
    StringBuilder/StringBuffer:构造数据填写length方法获得的实际值(默认16个字节) 
    ArrayList:已知元素个数填实际个数(默认值0)
    ConcurrentHashMap: 已知元素个数填实际个数(分配的是指定的2倍);
    -->
    <!--建议8.7.2 初始化集合时,给出初始化大小-->
    <module name="RegexpSingleline">
        <property name="format" value="new\s+(ArrayList|StringBuilder|StringBuffer|HashMap|HashSet|LinkedHashSet|ConcurrentHashMap|LinkedHashMap)(&lt;.*&gt;\(\)|\(\)|\(&quot;{2}\))"/>
        <property name="message" value="编程规范-建议8.7.2 : 初始化集合时,指定初始化大小"/>
    </module>
    <!-- 规则3.1  在条件语句和循环块中必须使用大括号 条件表达式用圆括号分组:方法调用不需要加圆括号 -->
    <module name="RegexpSingleline">
        <property name="format" value="(&amp;{2}|\|{2})\s*[^(]*[\w\.]*\s*(&lt;|&gt;|&gt;=|&lt;=|==|!=)+"/>
        <property name="message" value="编程规范-建议3.6 :超过1个的条件表达式应当用小圆括号分组"/>
    </module>
    <module name="RegexpSingleline">
        <property name="format" value="(&lt;|&gt;|&gt;=|&lt;=|==|!=)+\s*[\w\.]*[^)]\s*(&amp;{2}|\|{2})"/>
        <property name="message" value="编程规范-建议3.6 :超过1个的条件表达式应当用小圆括号分组"/>
    </module>
    <module name="RegexpSingleline">
        <property name="format" value="(&lt;|&gt;|&gt;=|&lt;=|==|!=)+\s*[\w\.]+[^)]\s*\?.*:"/>
        <property name="message" value="编程规范-建议3.6 :超过1个的条件表达式应当用小圆括号分组"/>
    </module>
    <!-- 规则4.1 不能用浮点数作为循环变量(循环变量在for条件之外声明无法检查)-->
    <module name="RegexpSingleline">
        <property name="format" value="^.*for\s+[(](float|double).*$"/>
        <property name="message" value="编程规范-规则4.1 :不能使用浮点数做循环变量"/>
    </module>
    <!-- 规则8.3.1 无需索引时采用for-each代替传统的for循环 (size在for条件之外调用无法检查)-->
    <module name="RegexpSingleline">
        <property name="format" value="^.*for\s+[(](\s*|\w+\s*\w+\s*=\s*0)\s*;.*;(\s*\)|\s*\w+\s*\+\+|\s*\+\+|\s*\w+\s*=(\s*\w+\s*\+\s*(1)|\s*(1)\s*+))"/>
        <property name="message" value="编程规范-规则8.3.1 :无需索引时采用for-each代替传统的for循环"/>
    </module>
    <module name="RegexpSingleline">
        <property name="format" value="^\s*//[^\u4e00-\u9fa5]*(\s*;|\{|\})$"/>
        <property name="message" value="编程规范-规则2.6 : 不用的代码段直接删除,不要注释掉"/>
    </module>
     <!-- 确实需要long对象时声明为long并已L结尾,否则使用暂用内存更少的int类型-->
    <module name="RegexpSingleline">
        <property name="format" value="long\s*\w+\s*=\s*\d+\s*;"/>
        <property name="message" value="long类型变量请显示填写L,或者改为int类型"/>
    </module>
    <!-- 规则7.2 不要通过一个空的catch块忽略异常-->
    <module name="RegexpMultiline">
        <property name="format" value="catch\s+[(][^)]*[)]\s+[{]\s+[}]"/>
        <property name="message" value="编程规范-规则7.2 : 不要通过一个空的catch块忽略异常"/>
    </module>
    <!-- 规则7.7 日志应分等级,对info及以下,使用条件形式或者使用占位符的方式 -->
    <module name="RegexpMultiline">
        <property name="format" value="(LOG|LOGGER|log|logger)\.(fatal|error|warn|info|debug)\((([^&quot;].+)|&quot;.+&quot;[^,])\s*(.*)\+"/>
        <property name="message" value="编程规范-规则7.7 : 日志应分等级,对info及以下,使用条件形式或者使用占位符的方式"/>
    </module>
    <!-- 只能检查整个类被注掉的情况 -->
    <!-- <module name="RegexpMultiline">
        <property name="format" value="/[*]+\s+(private|public|protected|static)+[^(]*[(]+[^)]*[)]+\s+[{]+[^\*/]*[\*/]+"/>
        <property name="message" value="编程规范-规则2.6 : 不用的代码段直接删除,不要注释掉"/>
    </module>-->

    <!-- 检查耗时较长规则,建议拷贝正则表达式IDE中直接搜索。默认注掉不开启 -->
    <!--<module name="RegexpMultiline">
        <property name="format" value="/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*(([^\u4e00-\u9fa5\s];\s*$)+)([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/"/>
        <property name="message" value="编程规范-规则2.6 : 不用的代码段直接删除,不要注释掉"/>
    </module>
    <module name="RegexpMultiline">
        <property name="format" value="^(\s*)\}\s*else\s+if.*\{[\r\n](\1\s+.*[\r\n]|\s*[\r\n])+\1\}\s*[\r\n]"/>
        <property name="message" value="编程规范-建议8.3.1 :对于if-else if(后续可能有多个else if)类型的条件判断,最后应该包含一个else分支"/>
    </module>
    <module name="RegexpMultiline">
        <property name="format" value="(LOG|LOGGER|log|logger)\.(fatal|error|warn|info|debug).*[\r\n]\s+.*[\u4e00-\u9fa5]+"/>
        <property name="message" value="禁止用中文打印日志"/>
    </module> -->

    <!-- 安全编程规范开始 -->
    <!-- 安全编程规范结束 -->
    <module name="TreeWalker">
        <!-- 关于注释:建议代码通过合理的命名、函数短小等方式,让代码有自注释能力,然后配以简要的注释说明,不建议大量的冗余注释 -->
        <module name="JavadocType">
            <!--检查类和接口的javadoc注释,要有描述、@author/@version等内容
            <property name="authorFormat" value="\S"/>-->
            <!-- 要有@author -->
            <!-- 版本格式暂时不限制 
            <property name="versionFormat" value="\S"/>-->
        </module>
        <module name="JavadocMethod">
            <!--检查方法和构造函数的javadoc注释-->
            <!-- protected以上都检查 ,由于protected以上都可能被他人使用或继承,所以必须给出相应的注释-->
            <property name="scope" value="protected"/>
            <!-- 不允许没有@param参数说明 -->
            <property name="allowMissingParamTags" value="false"/>
            <!-- 如果抛出异常不允许没有@throws -->
            <property name="allowMissingThrowsTags" value="false"/>
            <!-- 如果有返回值,不允许没有@return -->
            <property name="allowMissingReturnTag" value="false"/>
            <!-- 允许set/get方法没有javadoc -->
            <property name="allowMissingPropertyJavadoc " value="true"/>
            <!-- 不能在javadoc中的@throws中抛出RuntimeExceptions
                                             注意:在java中,可能在执行方法期间抛出但未被捕获的 RuntimeException 的任何子类都无需在 throws 子句中进行声明 -->
            <property name="logLoadErrors" value="true"/>
            <!--  logLoadErrors为true时将发现的问题只放到checkstyle报告-->
            <property name="suppressLoadErrors" value="true"/>
        </module>
        <module name="JavadocVariable">
            <!--检查变量的javadoc-->
            <property name="scope" value="public"/>
            <!-- public以上进行检查 -->
        </module>
        <module name="JavadocStyle">
            <!-- 检查javadoc的格式 -->
            <property name="checkFirstSentence" value="false"/>
            <!-- 不检查是否正常标点符号结尾 -->
            <property name="checkEmptyJavadoc" value="true"/>
            <!-- 检查空的javadoc -->
            <property name="checkHtml" value="false"/>
            <!-- 不检查html标签完整性 -->
        </module>
        <!-- 检查是否缺少@since标签 -->
        <module name="WriteTag">
            <property name="tag" value="@since"/>
            <property name="tagFormat" value="\S"/>
             <property name="tagSeverity" value="ignore"/>
        </module>
        <!--Size Violations:长度检查-->
        <module name="LineLength">
            <!-- 检查每行,最长120.忽略注释 -->
            <property name="ignorePattern" value="^ *\* *[^ ]+$"/>
            <property name="max" value="120"/>
        </module>
        <module name="AnonInnerLength">
            <!-- 检查内部类,最多60行 -->
            <property name="max" value="60"/>
        </module>
        <module name="MethodLength">
            <!-- 检查java方法,最大50 -->
            <property name="countEmpty" value="false"/>
            <property name="max" value="50"/>
        </module>
        <module name="ParameterNumber">
            <!-- 检查参数个数,最大5 -->
            <property name="max" value="5"/>
        </module>
        <!--Whitespace:空格检查-->
        <!-- 方法或构造函数调用声明时,不能和左括号之间有空格 -->
        <module name="MethodParamPad"/>
        <!-- ~, \-\-(减减前缀), ++(加加前缀), .(点),!,-(负号),+(正号)这些符号背后不允许接空格。-->
        <module name="NoWhitespaceAfter"/>
        <!-- ;, .(点), \-\-(后缀), ++(后缀)这些符合前面不允许有空格   -->
        <module name="NoWhitespaceBefore"/>
        <!-- 一行写不下换行时操作符放行首 -->
        <module name="OperatorWrap"/>
        <!-- 左圆括号右侧不能有空格,右圆括号左侧不能有空格,如不允许set( a.getString() ) -->
        <module name="ParenPad"/>
        <!-- 类型转换原则检查,不允许有空格,如 String s = ( String )s1; -->
        <module name="TypecastParenPad"/>
        <!-- 不能一行有多个参数声明,如int x,y,不便于理解和注释 -->
        <module name="MultipleVariableDeclarations"/>
        <module name="GenericWhitespace"/>
        <!-- 二元操作符前后需加空格。如比较操作符, 赋值操作符"="、 "+=",算术操作符"+"、"%",逻辑操作符"&&"、"&",位域操作符"<<"、"^"等 -->
        <module name="WhitespaceAround">
            <property name="tokens" value="COLON,NOT_EQUAL,QUESTION,DIV,DIV_ASSIGN,BXOR,BXOR_ASSIGN,MINUS,LCURLY,RCURLY,STAR,STAR_ASSIGN,TYPE_EXTENSION_AND,BAND,LAND,BAND_ASSIGN,MOD,MOD_ASSIGN,PLUS,PLUS_ASSIGN,LT,SL,SL_ASSIGN,LE,ASSIGN,MINUS_ASSIGN,EQUAL,GT,GE,SR,SR_ASSIGN,BSR,BSR_ASSIGN,BOR,BOR_ASSIGN,LOR,LITERAL_ASSERT,LITERAL_ASSERT,LITERAL_CATCH,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_RETURN,SLIST,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE"/>
        </module>
        <!-- 检查是否存在TODO(待处理) TODO是javaIDE自动生成的。一般代码写完后要去掉。 -->
        <module name="TodoComment">
            <property name="format" value="(TODO)|(FIXME)" />
        </module>
        <!--Modifiers:修饰符检查-->
        <!-- 检查修饰符顺序,正确的是1.public 2.protected 3.private 4.abstract 5.static 6.final 7.transient 8.volatile 9.synchronized 10.native 11.strictfp -->
        <module name="ModifierOrder"/>
        <!--Block Checks:关于{}的检查-->
        <module name="EmptyBlock"/>
        <!-- 不允许有空块,如{} -->
        <module name="LeftCurly">
            <!-- 左侧大括号放在一行结束的右边 -->
        </module>
        <module name="NeedBraces"/>
        <!-- if/eles while/do do/while for等要有{} -->
        <module name="RightCurly">
            <!-- 哪些情况右括号必须单独占行 -->
            <property name="option" value="alone"/>
            <property name="tokens" value="LITERAL_FINALLY, LITERAL_ELSE, CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT, INSTANCE_INIT"/>
        </module>
        <module name="RegexpSinglelineJava">
            <property name="format" value="printStackTrace"/>
            <property name="message" value="编程规范-规则7.4 : 不允许打印堆栈信息"/>
            <property name="ignoreComments" value="true"/>
        </module>
        <module name="RegexpSinglelineJava">
            <property name="format" value="System.out.print.*"/>
            <property name="message" value="编程规范-规则7.5 : 不允许使用控制台输出"/>
            <property name="ignoreComments" value="true"/>
        </module>
        <module name="MagicNumber">
            <!-- 魔鬼数字 -->
            <property name="ignoreNumbers" value="-1, 0, 1"/>
            <!-- 对-1/0/1不检查 -->
            <!--property name="ignoreHashCodeMethod" value="true"/-->
        </module>
        <!-- 检查不该抛出的异常,如未声明/Runtime -->
        <module name="IllegalThrows">
            <property name="illegalClassNames" value="java.lang.Error,java.lang.RuntimeException"/>
        </module>
        <module name="DeclarationOrder"/>
        <!-- 检查类、接口内声明顺序: 类成员变量(public/protected/package(default friendly)/private)/实例变量(顺序同变量))/构造函数/共有方法/私有方法-->
        <module name="UnnecessaryParentheses"/>
        <!-- 不能使用不必要的圆括号 -->
        <module name="StringLiteralEquality"/>
        <!-- String不能用=或!=来判断相同 -->
        <!--Class Design:类设计检查-->
        <module name="VisibilityModifier">
            <property name="packageAllowed" value="true"/>
            <property name="protectedAllowed" value="true"/>
        </module>
        <!-- 检查类成员对外可见性,只有Static final的可以是public对外访问-->
        <module name="HideUtilityClassConstructor"/>
        <!-- Utility类(只有静态成员和方法的类)不能有公有构造函数 -->
        <module name="ThrowsCount">
            <!-- 同一个方法声明时最多可以抛出5个异常 -->
            <property name="max" value="5"/>
        </module>
        <!-- 检查接口是否只定义了变量而没有定义方法,因为接口应该用来描述一个类型,所以只定义变量而不定义方法是不恰当的,from Effective Java-->
        <module name="InterfaceIsType"/>
        <!-- module name="CyclomaticComplexity"-->
        <!-- 圈复杂度检查 ,不能超过10,公司当前最新的要求就是10-->
        <!-- property name="max" value="10"/-->
        <!-- /module-->
        <!--Miscellaneous:杂项安全检查-->
        <module name="UpperEll"/>
        <!-- 定义使用long数据类型时用大写的L -->
        <module name="Indentation"/>
        <!-- 检查代码缩进对齐 -->
        <module name="UncommentedMain">
            <!-- 通过该属性排除进程启动类 -->
            <property name="excludedClasses" value="StartApplication"/>
            <!--<property name="excludedClasses" value="\.[a-zA-Z]*Main$"/>-->
        </module>
        <!-- 不能有没有用不到的main函数,建议测试代码用junit进行 -->
        <module name="Regexp">
            <property name="format" value="一句话功能简述"/>
            <!-- 不能出现“一句话功能简述”不清楚的注释,用自动生成的注释忽悠人 -->
            <property name="illegalPattern" value="true"/>
            <property name="message" value="请添加简单功能描述"/>
        </module>
        <module name="Regexp">
            <property name="format" value="功能详细描述"/>
            <property name="illegalPattern" value="true"/>
            <property name="message" value="请添加详细功能描述"/>
        </module>
        <!-- 第一章 命名检查开始-->
        <!--  规则1.2 import:import检查 -->
        <!-- 不能import*的方式引入包 -->
        <module name="AvoidStarImport"/>
        <!-- 不能重复引入 -->
        <module name="RedundantImport"/>
        <!-- 不能有无用的import -->
        <module name="UnusedImports"/>
        <!-- 检查空行分隔线:规则1.2 一个源文件按顺序包含版权、package、import、顶层类,且用空行分隔 -->
        <module name="EmptyLineSeparator"/>
        <module name="ConstantName">
            <!-- 常量命名检查 -->
            <property name="format" value="(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)|(^log$)|(^logger$)"/>
        </module>
        <module name="LocalFinalVariableName">
            <!-- 本地final变量命名检查 -->
            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
        </module>
        <module name="LocalVariableName">
            <!-- 本地变量名称检查 -->
            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
        </module>
        <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="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>
        <!-- 第一章 命名检查结束-->
        <!-- 第二章 注释检查开始-->
        <!--规则2.1 注释块标签顺序-->
        <module name="AtclauseOrder"/>
        <!-- 第二章 注释检查结束-->
        <!-- 第三章 排版检查开始-->
        <!-- 采用java风格还是c风格,例如:int[] num是java风格,int num[]是c风格。规则3.7 禁止C风格的数组声明-->
        <module name="ArrayTypeStyle"/>
        <!-- 建议3.7 变量被声明在接近它们首次使用的行-->
        <module name="VariableDeclarationUsageDistance">
            <property name="allowedDistance" value="3"/>
        </module>
        <!--建议3.8 应用于类,方法或构造方法的每个注解独占一行-->
        <module name="AnnotationLocation">
            <property name="allowSamelineMultipleAnnotations" value="false"/>
            <property name="allowSamelineSingleParameterlessAnnotation" value="false"/>
            <property name="allowSamelineParameterizedAnnotation" value="false"/>
        </module>
        <!-- 规则3.8 case语句块结束时如果不加break,需要有注释说明(fall-through) -->
        <module name="FallThrough">
            <property name="checkLastCaseGroup" value = "false"/>
            <property name="reliefPattern" value="^.*[fallthru|falls|fall]?\s+through.*$"/>
        </module>
        <!-- 规则3.9 switch语句要有default分支,除非switch的条件变量是枚举类型 -->
        <module name="MissingSwitchDefault"/>
        <module name="DefaultComesLast"/>
        <!-- 检查一行只有分号的情况 EmptyStatement  -->
        <module name="EmptyStatement"/>
        <!-- 第三章 排版检查结束-->
        <!-- 第四章 变量和类型检查开始-->
        <!-- -->
        <!-- 第四章 变量和类型检查结束-->
        <!-- 第五章 方法检查开始-->
        <!-- -->
        <module name="AvoidNestedBlocks">
            <!-- 不允许内嵌{} -->
            <property name="allowInSwitchCase" value="true"/>
            <!-- switch语句内允许 -->
        </module>
        <module name="NestedTryDepth">
            <!-- 内嵌的CheckStyle最大深度为2 -->
            <property name="max" value="4"/>
        </module>
        <module name="NestedIfDepth">
            <!-- 内嵌的if最大深度为4 -->
            <property name="max" value="3"/>
        </module>
        <module name="NestedForDepth">
            <property name="max" value="4"/>
        </module>
        <!--规则5.4 不要把方法的入参当做工作变量/临时变量(例外是方法中确实需要修改入参内容) -->
        <module name="ParameterAssignment"/>
        <!-- 第五章 方法检查结束-->
        <!-- 第六章 类和接口检查开始-->
        <!-- 规则6.1 避免在无关的变量或无关的概念之间重用名字,避免隐藏(hide)、遮蔽(shadow)和遮掩(obscure)-->
        <module name="HiddenField">
            <!-- 检查局部变量和参数屏蔽了类的成员 -->
            <property name="ignoreConstructorParameter" value="true"/>
            <!-- 忽略对构造函数的检查 -->
            <property name="ignoreSetter" value="true"/>
            <!-- 忽略对set方法的检查 -->
            <property name="ignoreAbstractMethods" value="true"/>
            <!-- 忽略对抽象方法的检查 -->
            <property name="setterCanReturnItsClass" value="true"/>
            <!-- 允许set方法的返回值为类对象 -->
        </module>
        <!-- 规则6.3 覆写equals方法时,应同时覆写hashCode方法-->
        <module name="EqualsHashCode"/>
        <!-- 建议6.3 接口定义中去掉多余的修饰词-->
        <module name="RedundantModifier"/>
        <!-- 规则6.4 子类覆写父类方法时应加上@Override注解-->
        <module name="MissingOverride"/>
        <!-- 第六章 类和接口检查结束-->
        <!-- 第七章 异常和日志检查开始-->
        <!-- -->
        <module name="IllegalCatch">
            <property name="illegalClassNames"
                  value="java.lang.Exception,
                         java.lang.Throwable,
                         java.lang.RuntimeException,
                         java.lang.NullPointerException"/>
        </module>
        <!-- 第七章 异常和日志检查结束-->
        <!-- -->
        <!-- 第八章 编程实践检查开始-->
        <!--采用Java1.5提供新并发工具代替wait和notify -->
        <module name="RegexpSinglelineJava">
            <property name="format" value="\.yield\(\)"/>
            <property name="message" value="编程规范-规则8.1.5 : 禁止使用yield方法"/>
        </module>
        <!--采用Java1.5提供新并发工具代替wait和notify -->
        <module name="RegexpSinglelineJava">
            <property name="format" value="\.wait\("/>
            <property name="message" value="编程规范-规则8.1.6 : 禁止使用wait方法"/>
        </module>
        <module name="RegexpSinglelineJava">
            <property name="format" value="\.setPriority\("/>
            <property name="message" value="编程规范-规则8.1.5 : 禁止使用setPriority方法"/>
        </module>
        <module name="RegexpSinglelineJava">
            <property name="format" value="\.notify\(\)"/>
            <property name="message" value="编程规范-规则8.1.6 : 禁止使用notify方法"/>
        </module>
        <module name="RegexpSinglelineJava">
            <property name="format" value="\.notifyAll\(\)"/>
            <property name="message" value="编程规范-规则8.1.6: 禁止使用notifyAll方法"/>
        </module>
        <!-- 建议8.2.1不要写超过3个的复杂条件表达式 -->
        <module name="BooleanExpressionComplexity"/>
        <!-- 规则8.6.1 不要使用已标注为@deprecated的方法-->
        <module name="SuppressWarnings">
            <property name="format" value="^unused$|^deprecation$|^static-access$|^serial$"/>
        </module>
        <!--规则8.7.7 禁止使用主动GC(除非在密码、RMI等方面),尤其是在频繁/周期性的逻辑中 -->
        <module name="RegexpSinglelineJava">
            <property name="format" value="System\.gc\(\)"/>
            <property name="message" value="编程规范-规则8.7.7: 禁止使用主动GC"/>
        </module>
        <!--规则8.7.8 禁止使用finalize()方法 -->
        <module name="RegexpSinglelineJava">
            <property name="format" value="finalize\(\)"/>
            <property name="message" value="编程规范-规则8.7.8 : 禁止使用finalize方法"/>
        </module>
        <!--规则8.8.1 不要在代码中硬编码"\n"和"\r"作为换行符号 -->
        <module name="RegexpSinglelineJava">
            <property name="format" value="\\n|\\r"/>
            <property name="message" value="编程规范-规则8.8.1: 请使用System.lineSeparator"/>
        </module>
        <!--规则8.9.2 不要依赖平台默认的字符编码方式,使用UTF-8 -->
        <module name="RegexpSinglelineJava">
            <property name="format" value="(\.getBytes\(\))|(\.bodyAsString\(\))"/>
            <property name="message" value="编程规范-规则8.9.2: 不要依赖默认编码格式,请显示指定为UTF-8"/>
        </module>
        <!--规则8.9.3 字符串大小写转换时,必须加上Locale.ENGLISH -->
        <module name="RegexpSinglelineJava">
            <property name="format" value="\.(toLowerCase|toUpperCase)\((Locale\.[^E][A-Z]+)?\)"/>
            <property name="message" value="编程规范-规则8.9.3: 字符串大小写转换时,必须加上Locale.ENGLISH"/>
        </module>
        <!-- 第八章 编程实践检查结束-->
    </module>
</module>
vieyahn2017 commented 5 years ago

findbug在pom.xml引入

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>findbugs-maven-plugin</artifactId>
                <version>3.0.3</version>
                <configuration>
                    <excludeFilterFile>./findbugs_exclude.xml</excludeFilterFile>
                    <classFilesDirectory>target/classes</classFilesDirectory>
                </configuration>
            </plugin>

findbugs_exclude.xml 排除具体指定

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

    <Match>
        <!--<Package name=""/>-->
        <Class name="com.xxxx.RestClient"/>
        <!--<Method name="alter"/>-->
        <Bug pattern="NP_NULL_ON_SOME_PATH_EXCEPTION"/>
    </Match>
    <Match>
        <Package name="com.xxxx.model.domain"/>
        <!--<Class name=""/>-->
        <!--<Method name="alter"/>-->
        <Bug pattern="EI_EXPOSE_REP"/>
    </Match>
    <Match>
        <Package name="com.xxxx.model.domain"/>
        <!--<Class name=""/>-->
        <!--<Method name="alter"/>-->
        <Bug pattern="EI_EXPOSE_REP2"/>
    </Match>
</FindBugsFilter>
vieyahn2017 commented 5 years ago

pmd_ruleset_minimal.xml

<?xml version="1.0" encoding="UTF-8"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         name="Favorites"
         xmlns="http://pmd.sf.net/ruleset/1.0.0"
         xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
         xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">

    <description>
        规则版本号:V1.4(2009-06-29)
        去除规则CloneMethodMustImplementCloneable

        规则版本号:V1.3(2009-06-15)
        去除规则UnnecessaryConstructor

        规则版本号:V1.2(2008-11-04)
        去除规则AvoidUsingHardCodedIP
        增加规则-------级别为3----------------------------------
        EmptyStaticInitializer、EmptyStatementNotInLoop、UnnecessaryFinalModifier、
        ExcessiveParameterList、UnnecessaryConstructor、DontImportSun、UseSingleton、
        AvoidDeeplyNestedIfStmts、DefaultLabelNotLastInSwitchStmt、NonCaseLabelInSwitchStatement、
        AvoidInstanceofChecksInCatchClause、SimplifyConditional、AvoidCallingFinalize、
        DontImportJavaLang、ImportFromSamePackage、BooleanGetMethodName、
        SignatureDeclareThrowsException、AvoidThrowingRawExceptionTypes、DoNotExtendJavaLangError
        -------级别为4----------------------------------
        OverrideBothEqualsAndHashcode、EmptySynchronizedBlock、UselessOperationOnImmutable、
        MisplacedNullCheck、BrokenNullCheck、IfStmtsMustUseBraces、WhileLoopsMustUseBraces、
        IfElseStmtsMustUseBraces、ForLoopsMustUseBraces、AvoidAccessibilityAlteration、
        DoNotCallGarbageCollectionExplicitly、BadComparison、InstantiationToGetClass、
        UseNotifyAllInsteadOfNotify、ReturnEmptyArrayRatherThanNull、StringInstantiation、
        StringToString、UseEqualsToCompareStrings、UnusedPrivateField、UnusedPrivateMethod

        规则版本号:V1.1(2008-08-13)
        去除规则ShortVariable

        规则版本号:V1.0(2008-08-11)
        推荐指数是4、5级的规则。
    </description>

    <!--====================Basic Rules begin(共33个)======================-->
    <rule ref="rulesets/java/basic.xml/EmptyCatchBlock">
        <properties>
            <property name="allowCommentedBlocks" value="false"/>
        </properties>
    </rule>
    <!--不允许出现空的catch块,避免屏蔽异常,不处理或不报告异常。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/EmptyIfStmt"/>
    <!--不允许有空if语句块(或空else块)。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/EmptyWhileStmt"/>
    <!--不允许有空while循环块。注意:不包括do循环。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/EmptyTryBlock"/>
    <!--不允许有空try块。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/EmptyFinallyBlock"/>
    <!--不允许有空finally块。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/EmptySwitchStatements"/>
    <!--不允许有空switch块。与这个规则重复:rulesets/design.xml/SwitchStmtsShouldHaveDefault、MissingBreakInSwitch。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/JumbledIncrementer"/>
    <!--避免混乱的循环变量赋值(避免在内循环里修改外循环变量)。与这个规则有点重复:rulesets/controversial.xml/DataflowAnomalyAnalysis。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/basic.xml/ForLoopShouldBeWhileLoop"/-->
    <!--简单的for循环可以用while循环取代。(FindBugs不检查,注,FindBugs能发现死循环)-->
    <!--rule ref="rulesets/java/basic.xml/UnnecessaryConversionTemporary"/-->
    <!--当基本型数据转换成String时,避免不必要的临时对象。(FindBugs检查)-->
    <rule ref="rulesets/java/basic.xml/OverrideBothEqualsAndHashcode"/>
    <!--equals和hashcode同时定义。(FindBugs检查)-->
    <!--rule ref="rulesets/java/basic.xml/DoubleCheckedLocking"/-->
    <!--doublecheck问题。(FindBugs检查)-->
    <rule ref="rulesets/java/basic.xml/ReturnFromFinallyBlock"/>
    <!--禁止在finally块里return,避免屏蔽异常。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/EmptySynchronizedBlock"/>
    <!--避免空的同步块。(FindBugs检查)-->
    <!--rule ref="rulesets/java/basic.xml/UnnecessaryReturn"/-->
    <!--方法返回值void,避免不必要的return。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/EmptyStaticInitializer"/>
    <!--空的static初始化。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/UnconditionalIfStatement"/>
    <!--if语句的条件始终是true或false。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/EmptyStatementNotInLoop"/>
    <!--出现了空语句(就一个分号),如果在循环里则可以。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/BooleanInstantiation"/>
    <!--避免实例化Boolean对象,而应用常量Boolean.TRUE, Boolean.FALSE。(FindBugs只检查构造方法生成对象的情况,不检查valueOf)-->
    <rule ref="rulesets/java/basic.xml/UnnecessaryFinalModifier"/>
    <!--当一个类定义成final后,它所有的方法自动final。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/basic.xml/CollapsibleIfStatements"/-->
    <!--内嵌的if语句能够和外层的if语句合并成一个if语句。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/basic.xml/UselessOverridingMethod"/-->
    <!--被覆盖的方法仅仅调用了基类的方法。(FindBugs检查)-->
    <rule ref="rulesets/java/basic.xml/ClassCastExceptionWithToArray"/>
    <!--Collection.toArray调用转换成数组,应主动传一个明确类型的数组对象,否则运行时会抛ClassCastException异常。相似规则:rulesets/design.xml/OptimizableToArrayCall。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/AvoidDecimalLiteralsInBigDecimalConstructor"/>
    <!--new BigDecimal建议用String参数的构造方法,而不是十进制小数常量(整数除外)。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/UselessOperationOnImmutable"/>
    <!--不可变对象(如BigDecimal、BigInteger)上的操作结果被忽略。(FindBugs检查)-->
    <rule ref="rulesets/java/basic.xml/MisplacedNullCheck"/>
    <!--空指针判断放错了位置。要么之前已报空指针,要么此处永远不可能是空指针。(FindBugs检查)-->
    <!--rule ref="rulesets/java/basic.xml/UnusedNullCheckInEquals"/-->
    <!--在判断了对象是否是空指针后,后面紧接着调用该对象的equals方法,而不是将对象作为另一个对象的equals参数。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/basic.xml/AvoidThreadGroup"/-->
    <!--不建议用ThreadGroup,因为它的方法不是线程安全的。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/BrokenNullCheck"/>
    <!--应该用&&取代||或反之。(FindBugs检查)-->
    <rule ref="rulesets/java/basic.xml/BigIntegerInstantiation"/>
    <!--不要再创建已经有的对象(BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN)。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/basic.xml/AvoidUsingOctalValues"/-->
    <!--避免使用八进制值。(FindBugs不检查)-->
    <!--
    <rule ref="rulesets/java/basic.xml/AvoidUsingHardCodedIP">
      <properties>
          <property name="pattern" value=""/>
      </properties>
    </rule>
    -->
    <!--避免硬编码IPv4和IPv6,以免在某些情况下变的不可能布署。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/CheckResultSet"/>
    <!--对ResultSet的方法(next,previous,first,last)调用结果要进行是否是真的判断。(FindBugs不检查)-->
    <rule ref="rulesets/java/basic.xml/AvoidMultipleUnaryOperators"/>
    <!--避免多个一元操作符,要么是一个错误,要么易引起混淆。(FindBugs不检查)-->
    <!--====================Basic Rules end======================-->

    <!--====================braces Rules begin(共4个)======================-->
    <rule ref="rulesets/java/braces.xml/IfStmtsMustUseBraces"/>
    <rule ref="rulesets/java/braces.xml/WhileLoopsMustUseBraces"/>
    <rule ref="rulesets/java/braces.xml/IfElseStmtsMustUseBraces"/>
    <rule ref="rulesets/java/braces.xml/ForLoopsMustUseBraces"/>
    <!--====================braces Rules end======================-->

    <!--====================clone Rules begin(共3个)======================-->
    <rule ref="rulesets/java/clone.xml/ProperCloneImplementation"/>
    <rule ref="rulesets/java/clone.xml/CloneThrowsCloneNotSupportedException"/>
    <!--rule ref="rulesets/java/clone.xml/CloneMethodMustImplementCloneable"/-->
    <!--====================clone Rules end======================-->

    <!--====================codesize Rules begin(共11个)======================-->
    <!--
    <rule ref="rulesets/java/codesize.xml/NPathComplexity">
        <properties>
           <property name="minimum" value="200"/>
        </properties>
    </rule>
    -->
    <!--
    <rule ref="rulesets/java/codesize.xml/ExcessiveMethodLength">
        <properties>
           <property name="minimum" value="100"/>
        </properties>
    </rule>
    -->
    <rule ref="rulesets/java/codesize.xml/ExcessiveParameterList">
        <properties>
            <property name="minimum" value="15"/>
        </properties>
    </rule>
    <!--
    <rule ref="rulesets/java/codesize.xml/ExcessiveClassLength">
        <properties>
           <property name="minimum" value="1000"/>
        </properties>
    </rule>
    -->
    <!--
    <rule ref="rulesets/java/codesize.xml/CyclomaticComplexity">
        <properties>
           <property name="reportLevel" value="10"/>
           property name="showClassesComplexity" value="true"/>
           property name="showMethodsComplexity" value="true"/>
        </properties>
    </rule>
    -->
    <!--
    <rule ref="rulesets/java/codesize.xml/ExcessivePublicCount">
        <properties>
           <property name="minimum" value="45"/>
        </properties>
    </rule>
    -->
    <!--
    <rule ref="rulesets/java/codesize.xml/TooManyFields">
        <properties>
           <property name="maxfields" value="15"/>
        </properties>
    </rule>
    -->
    <!--
    <rule ref="rulesets/java/codesize.xml/NcssMethodCount">
        <properties>
           <property name="minimum" value="100"/>
        </properties>
    </rule>
     -->
    <!--
   <rule ref="rulesets/java/codesize.xml/NcssTypeCount">
       <properties>
          <property name="minimum" value="1500"/>
       </properties>
   </rule>
   -->
    <!--
    <rule ref="rulesets/java/codesize.xml/NcssConstructorCount">
        <properties>
           <property name="minimum" value="100"/>
        </properties>
    </rule>
     -->
    <!--
   <rule ref="rulesets/java/codesize.xml/TooManyMethods">
       <properties>
          <property name="maxmethods" value="20"/>
       </properties>
   </rule>
   -->
    <!--====================codesize Rules end======================-->

    <!--====================controversial Rules begin(共19个)======================-->
    <!--rule ref="rulesets/java/controversial.xml/UnnecessaryConstructor"/-->
    <!--rule ref="rulesets/java/controversial.xml/NullAssignment"/-->
    <!--rule ref="rulesets/java/controversial.xml/OnlyOneReturn"/-->
    <!--rule ref="rulesets/java/controversial.xml/UnusedModifier"/-->
    <!--rule ref="rulesets/java/controversial.xml/AssignmentInOperand"/-->
    <!--rule ref="rulesets/java/controversial.xml/AtLeastOneConstructor"/-->
    <rule ref="rulesets/java/controversial.xml/DontImportSun"/>
    <!--rule ref="rulesets/java/controversial.xml/SuspiciousOctalEscape"/-->
    <!--rule ref="rulesets/java/controversial.xml/CallSuperInConstructor"/-->
    <!--rule ref="rulesets/java/controversial.xml/UnnecessaryParentheses"/-->
    <!--rule ref="rulesets/java/controversial.xml/DefaultPackage"/-->
    <!--rule ref="rulesets/java/controversial.xml/BooleanInversion"/-->
    <!--
    <rule ref="rulesets/java/controversial.xml/DataflowAnomalyAnalysis">
          <properties>
           <property name="maxviolations" value="100"/>
           <property name="maxpaths" value="1000"/>
        </properties>
    </rule>
    -->
    <!--rule ref="rulesets/java/controversial.xml/AvoidFinalLocalVariable"/-->
    <!--rule ref="rulesets/java/controversial.xml/AvoidUsingShortType"/-->
    <!--rule ref="rulesets/java/controversial.xml/AvoidUsingVolatile"/-->
    <!--rule ref="rulesets/java/controversial.xml/AvoidUsingNativeCode"/-->
    <rule ref="rulesets/java/controversial.xml/AvoidAccessibilityAlteration"/>
    <rule ref="rulesets/java/controversial.xml/DoNotCallGarbageCollectionExplicitly"/>
    <!--====================controversial Rules end======================-->

    <!--====================coupling Rules begin(共3个)======================-->
    <!--
   <rule ref="rulesets/java/coupling.xml/CouplingBetweenObjects">
       <properties>
          <property name="threshold" value="20"/>
       </properties>
   </rule>
   -->
    <!--
    <rule ref="rulesets/java/coupling.xml/ExcessiveImports">
        <properties>
           <property name="minimum" value="30"/>
        </properties>
    </rule>
    -->
    <!--<rule ref="rulesets/java/coupling.xml/LooseCoupling"/>-->
    <!--====================coupling Rules end======================-->

    <!--====================Design Rules begin(共48个)======================-->
    <rule ref="rulesets/java/design.xml/UseSingleton"/>
    <!--如果成员方法都是static,建议使用Singletom模式,或定义成abstract类。(FindBugs不检查)-->
    <rule ref="rulesets/java/design.xml/SimplifyBooleanReturns"/>
    <!--避免以下代码
          if (bar == x) {
          return true;
          } else {
          return false;
          }(FindBugs不检查)
   -->
    <rule ref="rulesets/java/design.xml/SimplifyBooleanExpressions"/>
    <!--避免以下代码
          boolean bar = (isFoo() == true);(FindBugs不检查)
    -->
    <rule ref="rulesets/java/design.xml/SwitchStmtsShouldHaveDefault"/>
    <!--switch语句应该有一个default。(FindBugs不检查)-->
    <rule ref="rulesets/java/design.xml/AvoidDeeplyNestedIfStmts">
        <properties>
            <property name="problemDepth" value="5"/>
        </properties>
    </rule>
    <!--避免较深的if语句,注意:有else的不算。(FindBugs不检查)-->
    <!--
    <rule ref="rulesets/java/design.xml/AvoidReassigningParameters"/>
    -->
    <!--避免方法参数未使用就被赋值。(FindBugs检查)-->
    <!--不用
    <rule ref="rulesets/java/design.xml/SwitchDensity">
      <properties>
          <property name="minimum" value="10"/>
      </properties>
    </rule>
    -->
    <!--label下的语句太多,建议优化重构。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/design.xml/ConstructorCallsOverridableMethod"/-->
    <!-- 在构造方法中调用了可能会被覆盖的成员方法,后果:可能会有空指针错误。(FindBugs不检查) -->
    <rule ref="rulesets/java/design.xml/AccessorClassGeneration"/>
    <!-- 避免以下代码,私有构造方法类在类定义外生成实例,这会导致the generation of an accessor。(FindBugs不检查)
          public class Outer {
           void method(){
            Inner ic = new Inner();//Causes generation of accessor class
           }
           public class Inner {
            private Inner(){}
           }
          }
     -->
    <rule ref="rulesets/java/design.xml/FinalFieldCouldBeStatic"/>
    <!-- final成员变量(field,类字段)建议定义成static,这样可以节省空间 。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/design.xml/CloseResource"/-->
    <!-- Connection,Statement,ResultSet对象使用后要close。(FindBugs不检查) -->
    <!--rule ref="rulesets/java/design.xml/NonStaticInitializer"/-->
    <!-- 不建议使用非静态初始化块 ,易引起混乱。(FindBugs不检查)-->
    <rule ref="rulesets/java/design.xml/DefaultLabelNotLastInSwitchStmt"/>
    <!-- switch中的default应放在最后一个。(FindBugs不检查)-->
    <rule ref="rulesets/java/design.xml/NonCaseLabelInSwitchStatement"/>
    <!-- switch中有非case的label。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/design.xml/OptimizableToArrayCall"/-->
    <!-- Collection.toArray(T[] a)调用中new a数组时要指定数组长度。(FindBugs检查)-->
    <rule ref="rulesets/java/design.xml/BadComparison"/>
    <!-- 避免与Double.NaN进行是否相等比较(==)。(FindBugs检查)-->
    <rule ref="rulesets/java/design.xml/EqualsNull"/>
    <!-- 避免与null比较,如x.equals(null) (FindBugs不检查)-->
    <!--
    <rule ref="rulesets/java/design.xml/ConfusingTernary"/>
    -->
    <!-- 避免if(x!=y),要先if(x==y) (FindBugs不检查)-->
    <rule ref="rulesets/java/design.xml/InstantiationToGetClass"/>
    <!-- 为了获得Class对象,请用类的class成员,而不要实例化对象然后getClass (FindBugs检查)-->
    <!--rule ref="rulesets/java/design.xml/IdempotentOperations"/-->
    <!-- 避免幂等操作,如变量赋值给它自己 (FindBugs检查)-->
    <!--rule ref="rulesets/java/design.xml/SimpleDateFormatNeedsLocale"/-->
    <!-- 生成SimpleDateFormat实例的时候要求指定Locale(FindBugs不检查) -->
    <!--rule ref="rulesets/java/design.xml/ImmutableField"/-->
    <!-- field在变量定义时或构造方法中赋值后就再也没有改变过,则可以定义成final的。(FindBugs不检查) -->
    <!--rule ref="rulesets/java/design.xml/UseLocaleWithCaseConversions"/-->
    <!-- 在进行大小字转换(String.toLowerCase()/toUpperCase() )的时候请使用Locale,可以避免某些Locale带来的问题(FindBugs检查)-->
    <!--rule ref="rulesets/java/design.xml/AvoidProtectedFieldInFinalClass"/-->
    <!-- final类不要出现protected字段(FindBugs检查)-->
    <!--rule ref="rulesets/java/design.xml/AssignmentToNonFinalStatic"/-->
    <!-- 赋值给静态非final变量,可能会不安全。在静态区赋值或定义时赋值则没问题。(FindBugs检查)-->
    <rule ref="rulesets/java/design.xml/MissingStaticMethodInNonInstantiatableClass"/>
    <!-- 在不能实例化的类里(定义了私有构造方法的类)没有静态方法,这样这个类不可用。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/design.xml/AvoidSynchronizedAtMethodLevel"/-->
    <!-- 用块级别的同步代替方法级的同步,这样能够保证让真正需要的代码同步(FindBugs不检查)-->
    <!--rule ref="rulesets/java/design.xml/MissingBreakInSwitch"/-->
    <!-- case没有break(FindBugs检查)-->
    <rule ref="rulesets/java/design.xml/UseNotifyAllInsteadOfNotify"/>
    <!-- 用notifyAll取代notify(FindBugs检查)-->
    <rule ref="rulesets/java/design.xml/AvoidInstanceofChecksInCatchClause"/>
    <!-- 避免在catch子句里再判断具体的异常类型,就是用instanceof。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/design.xml/AbstractClassWithoutAbstractMethod"/-->
    <!-- 抽象类没有定义任何抽象方法,如果类仅希望作为基类使用,但又不需要抽象方法,则建议提供一个protected构造方法。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/design.xml/SimplifyConditional"/-->
    <!-- 条件表达式中没有必要在instanceof之前进行空指针判断。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/design.xml/CompareObjectsWithEquals"/-->
    <!-- 建议用equals对象,而不是用==.(FindBugs检查)-->
    <!--rule ref="rulesets/java/design.xml/PositionLiteralsFirstInComparisons"/-->
    <!-- 字符串变量与常量比较时,先写常量,这样可以避免空指针异常。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/design.xml/UnnecessaryLocalBeforeReturn"/-->
    <!-- 避免不必要的本地变量。(FindBugs不检查)-->
    <!--
    <rule ref="rulesets/java/design.xml/NonThreadSafeSingleton">
       <properties>
          <property name="checkNonStaticMethods" value="true"/>
          <property name="checkNonStaticFields" value="true"/>
       </properties>
    </rule>
    -->
    <!-- 线程不安全的Singleton。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/design.xml/UncommentedEmptyMethod"/-->
    <!-- 未加注释的空方法,在方法的花括弧之间未加注释。(FindBugs不检查)-->
    <!--
    <rule ref="rulesets/java/design.xml/UncommentedEmptyConstructor">
        <properties>
          <property name="ignoreExplicitConstructorInvocation" value="true"/>
       </properties>
    </rule>
    -->
    <!-- 未加注释的空构造方法,在方法的花括弧之间未加注释。注意,在super或this前的注释不算。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/design.xml/AvoidConstantsInterface"/-->
    <!-- 避免只有常量的接口定义,可以考虑将其转换成类。(FindBugs不检查)-->
    <!--rule ref="rulesets/java/design.xml/UnsynchronizedStaticDateFormatter"/-->
    <!-- 静态SimpleDateFormat成员变量访问未加同步。(FindBugs检查,另外FindBugs不建议定义静态SimpleDateFormat成员变量)-->
    <rule ref="rulesets/java/design.xml/PreserveStackTrace"/>
    <!-- catch到了异常后又重新throw新的异常,未保留源异常,源异常的stack trace可能会丢失,不利于程序调试。(FindBugs不检查)-->
    <rule ref="rulesets/java/design.xml/UseCollectionIsEmpty"/>
    <!-- 对Collection对象,建议用isEmpty()取代size()与0的判断。(FindBugs不检查)-->
    <rule ref="rulesets/java/design.xml/ClassWithOnlyPrivateConstructorsShouldBeFinal"/>
    <!-- 只有私有构造方法的类应该申明为final的,除非构造方法被内部类调用。注,私有构造方法的类能够被它的内部类使用。(FindBugs不检查)-->
    <!--
    <rule ref="rulesets/java/design.xml/EmptyMethodInAbstractClassShouldBeAbstract"/>
    -->
    <!-- 抽象类里的空方法应该定义成abstract。(FindBugs不检查)-->
    <!--
    <rule ref="rulesets/java/design.xml/SingularField">
       <properties>
          <property name="CheckInnerClasses" value="true"/>
          <property name="DisallowNotAssignment" value="true"/>
       </properties>
    </rule>
    -->
    <!-- 某个类字段仅在一个方法中使用,建议改用本地变量。构造方法中有赋值不算,但定义时有初始值算。(FindBugs不检查)-->
    <rule ref="rulesets/java/design.xml/ReturnEmptyArrayRatherThanNull"/>
    <!-- 返回空数组,而不是null。(FindBugs检查)-->
    <!--rule ref="rulesets/java/design.xml/AbstractClassWithoutAnyMethod"/-->
    <!-- 如果一个抽象类不包含任何方法,只有数据字段,则建议定义private或protected的构造方法以不允许实例化。(FindBugs不检查)-->
    <rule ref="rulesets/java/design.xml/TooFewBranchesForASwitchStatement"/>
    <!--
    <properties>
       <property name="minimumNumberCaseForASwitch" value="3"/>
    </properties>
    -->
    <!-- switch的case语句如果太少的话建议用if取代,以增加代码可读性。(FindBugs不检查)-->
    <!--====================Design Rules end======================-->

    <!--====================finalizers Rules begin(共6个)======================-->
    <rule ref="rulesets/java/finalizers.xml/EmptyFinalizer"/>
    <rule ref="rulesets/java/finalizers.xml/FinalizeOnlyCallsSuperFinalize"/>
    <rule ref="rulesets/java/finalizers.xml/FinalizeOverloaded"/>
    <rule ref="rulesets/java/finalizers.xml/FinalizeDoesNotCallSuperFinalize"/>
    <!--rule ref="rulesets/java/finalizers.xml/FinalizeShouldBeProtected"/-->
    <rule ref="rulesets/java/finalizers.xml/AvoidCallingFinalize"/>
    <!--====================finalizers Rules end======================-->

    <!--====================imports Rules begin(共5个)======================-->
    <rule ref="rulesets/java/imports.xml/DuplicateImports"/>
    <rule ref="rulesets/java/imports.xml/DontImportJavaLang"/>
    <rule ref="rulesets/java/imports.xml/UnusedImports"/>
    <rule ref="rulesets/java/imports.xml/ImportFromSamePackage"/>
    <!--
    <rule ref="rulesets/java/imports.xml/TooManyStaticImports">
        <properties>
           <property name="maximumStaticImports" value="4"/>
        </properties>
    </rule>
    -->
    <!--====================imports Rules end======================-->

    <!--====================j2ee Rules begin(共9个)======================-->
    <!--rule ref="rulesets/java/j2ee.xml/UseProperClassLoader"/-->
    <!--rule ref="rulesets/java/j2ee.xml/MDBAndSessionBeanNamingConvention"/-->
    <!--rule ref="rulesets/java/j2ee.xml/RemoteSessionInterfaceNamingConvention"/-->
    <!--rule ref="rulesets/java/j2ee.xml/LocalInterfaceSessionNamingConvention"/-->
    <!--rule ref="rulesets/java/j2ee.xml/LocalHomeNamingConvention"/-->
    <!--rule ref="rulesets/java/j2ee.xml/RemoteInterfaceNamingConvention"/-->
    <!--rule ref="rulesets/java/j2ee.xml/DoNotCallSystemExit"/-->
    <!--rule ref="rulesets/java/j2ee.xml/StaticEJBFieldShouldBeFinal"/-->
    <!--rule ref="rulesets/java/j2ee.xml/DoNotUseThreads"/-->
    <!--====================j2ee Rules end======================-->

    <!--====================logging-jakarta-commons Rules begin(共2个)======================-->
    <!--rule ref="rulesets/java/logging-jakarta-commons.xml/UseCorrectExceptionLogging"/-->
    <!--
    <rule ref="rulesets/java/logging-jakarta-commons.xml/ProperLogger">
        <properties>
           <property name="staticLoggerName" value="log"/>
        </properties>
    </rule>
    -->
    <!--====================logging-jakarta-commons Rules end======================-->

    <!--====================logging-java Rules begin(共4个)======================-->
    <rule ref="rulesets/java/logging-java.xml/MoreThanOneLogger"/>
    <!--rule ref="rulesets/java/logging-java.xml/LoggerIsNotStaticFinal"/-->
    <rule ref="rulesets/java/logging-java.xml/SystemPrintln"/>
    <rule ref="rulesets/java/logging-java.xml/AvoidPrintStackTrace"/>
    <!--====================logging-java Rules end======================-->

    <!--====================naming Rules begin(共18个)======================-->
    <!--rule ref="rulesets/java/naming.xml/ShortVariable"/-->
    <!--
    <rule ref="rulesets/java/naming.xml/LongVariable">
        <properties>
           <property name="minimum" value="40"/>
        </properties>
    </rule>
    -->
    <rule ref="rulesets/java/naming.xml/ShortMethodName"/>
    <rule ref="rulesets/java/naming.xml/VariableNamingConventions"/>
    <rule ref="rulesets/java/naming.xml/MethodNamingConventions"/>
    <rule ref="rulesets/java/naming.xml/ClassNamingConventions"/>
    <!--rule ref="rulesets/java/naming.xml/AbstractNaming"/-->
    <rule ref="rulesets/java/naming.xml/AvoidDollarSigns"/>
    <rule ref="rulesets/java/naming.xml/MethodWithSameNameAsEnclosingClass"/>
    <rule ref="rulesets/java/naming.xml/SuspiciousHashcodeMethodName"/>
    <rule ref="rulesets/java/naming.xml/SuspiciousConstantFieldName"/>
    <rule ref="rulesets/java/naming.xml/SuspiciousEqualsMethodName"/>
    <rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingTypeName"/>
    <rule ref="rulesets/java/naming.xml/AvoidFieldNameMatchingMethodName"/>
    <rule ref="rulesets/java/naming.xml/NoPackage"/>
    <rule ref="rulesets/java/naming.xml/PackageCase"/>
    <rule ref="rulesets/java/naming.xml/MisleadingVariableName"/>
    <rule ref="rulesets/java/naming.xml/BooleanGetMethodName">
        <properties>
            <property name="checkParameterizedMethods" value="false"/>
        </properties>
    </rule>
    <!--====================naming Rules end======================-->

    <!--====================optimization Rules begin(共10个)======================-->
    <!--rule ref="rulesets/java/optimizations.xml/LocalVariableCouldBeFinal"/-->
    <!--rule ref="rulesets/java/optimizations.xml/MethodArgumentCouldBeFinal"/-->
    <!--rule ref="rulesets/java/optimizations.xml/AvoidInstantiatingObjectsInLoops"/-->
    <rule ref="rulesets/java/optimizations.xml/UseArrayListInsteadOfVector"/>
    <!--rule ref="rulesets/java/optimizations.xml/SimplifyStartsWith"/-->
    <!--rule ref="rulesets/java/optimizations.xml/UseStringBufferForStringAppends"/-->
    <rule ref="rulesets/java/optimizations.xml/UseArraysAsList"/>
    <rule ref="rulesets/java/optimizations.xml/AvoidArrayLoops"/>
    <rule ref="rulesets/java/optimizations.xml/UnnecessaryWrapperObjectCreation"/>
    <!--rule ref="rulesets/java/optimizations.xml/AddEmptyString"/-->
    <!--====================optimization Rules end======================-->

    <!--====================strictexception Rules begin(共9个)======================-->
    <rule ref="rulesets/java/strictexception.xml/AvoidCatchingThrowable"/>
    <rule ref="rulesets/java/strictexception.xml/SignatureDeclareThrowsException"/>
    <rule ref="rulesets/java/strictexception.xml/ExceptionAsFlowControl"/>
    <rule ref="rulesets/java/strictexception.xml/AvoidCatchingNPE"/>
    <rule ref="rulesets/java/strictexception.xml/AvoidThrowingRawExceptionTypes"/>
    <!--rule ref="rulesets/java/strictexception.xml/AvoidThrowingNullPointerException"/-->
    <rule ref="rulesets/java/strictexception.xml/AvoidRethrowingException"/>
    <rule ref="rulesets/java/strictexception.xml/DoNotExtendJavaLangError"/>
    <rule ref="rulesets/java/strictexception.xml/DoNotThrowExceptionInFinally"/>
    <!--====================strictexception Rules end======================-->

    <!--====================sunsecure Rules begin(共2个)======================-->
    <!--rule ref="rulesets/java/sunsecure.xml/MethodReturnsInternalArray"/-->
    <!--rule ref="rulesets/java/sunsecure.xml/ArrayIsStoredDirectly"/-->
    <!--====================sunsecure Rules end======================-->

    <!--====================strings Rules begin(共15个)======================-->
    <!--
    <rule ref="rulesets/java/strings.xml/AvoidDuplicateLiterals">
        <properties>
           <property name="threshold" value="4"/>
        </properties>
    </rule>
    -->
    <rule ref="rulesets/java/strings.xml/StringInstantiation"/>
    <rule ref="rulesets/java/strings.xml/StringToString"/>
    <!--rule ref="rulesets/java/strings.xml/InefficientStringBuffering"/-->
    <rule ref="rulesets/java/strings.xml/UnnecessaryCaseChange"/>
    <rule ref="rulesets/java/strings.xml/UseStringBufferLength"/>
    <rule ref="rulesets/java/strings.xml/AppendCharacterWithChar"/>
    <!--
    <rule ref="rulesets/java/strings.xml/ConsecutiveLiteralAppends">
        <properties>
           <property name="threshold" value="1"/>
        </properties>
    </rule>
    -->
    <!--rule ref="rulesets/java/strings.xml/UseIndexOfChar"/-->
    <!--rule ref="rulesets/java/strings.xml/InefficientEmptyStringCheck"/-->
    <!--rule ref="rulesets/java/strings.xml/InsufficientStringBufferDeclaration"/-->
    <rule ref="rulesets/java/strings.xml/UselessStringValueOf"/>
    <rule ref="rulesets/java/strings.xml/StringBufferInstantiationWithChar"/>
    <rule ref="rulesets/java/strings.xml/UseEqualsToCompareStrings"/>
    <!--rule ref="rulesets/java/strings.xml/AvoidStringBufferField"/-->
    <!--====================strings Rules end======================-->

    <!--====================unusedcode Rules begin(共4个)======================-->
    <rule ref="rulesets/java/unusedcode.xml/UnusedPrivateField"/>
    <rule ref="rulesets/java/unusedcode.xml/UnusedLocalVariable"/>
    <rule ref="rulesets/java/unusedcode.xml/UnusedPrivateMethod"/>
    <rule ref="rulesets/java/unusedcode.xml/UnusedFormalParameter"/>
    <!--====================unusedcode Rules end======================-->

</ruleset>
vieyahn2017 commented 5 years ago

Java后端开发规范

基于阿里巴巴JAVA开发规范整理

https://www.cnblogs.com/chenshengjava/p/8922392.html

vieyahn2017 commented 5 years ago

谈谈ali与Google的Java开发规范

https://www.jianshu.com/p/41e134657902

sherlockyb 2018.01.07 13:08 字数 10479 无规矩不成方圆,编码规范就如同协议,有了Http、TCP等各种协议,计算机之间才能有效地通信,同样的,有了一致的编码规范,程序员之间才能有效地合作。道理大家都懂,可现实中的我们,经常一边吐槽别人的代码,一边写着被吐槽的代码,究其根本,就是缺乏遵从编码规范的意识!多年前,Google发布Google Java Style来定义Java编码时应遵循的规范;今年年初阿里则发布阿里巴巴Java 开发手册,并随后迭代了多个版本,直至9月份又发布了pdf终极版。这两大互联网巨头的初衷,都是希望能够统一标准,使业界编码达到一致性,提升沟通和研发效率,这对于我们码农无疑是很赞的一笔福利呀。笔者将两份规范都通读了一遍,其中列举的不少细则跟平时的编码习惯基本是符合的,不过还是有不少新奇的收获,忍不住记录在此,供日后念念不忘~

Java开发规范总览

一、Google Java Style

Google的java开发规范主要分为6大部分:源文件基本规范、源文件结构、代码格式、命名、编程实践和Javadoc,各部分概要如下:

1、源文件基本规范(source file basics):文件名、文件编码、特殊字符的规范要求 2、源文件结构(source file structure):版权许可信息、package、import、类申明的规约 3、代码格式(formatting):大括号、缩进、换行、列长限制、空格、括号、枚举、数组、switch语句、注4、解、注释、和修饰符等格式要求 5、命名(Naming):标识符、包名、类名、方法名、常量名、非常量成员名、参数名、局部变量的命名规范 6、编程实践(Programming Practices):@override、异常捕获、静态成员、Finalizers等用法规约

二、阿里巴巴Java开发手册

阿里的Java开发手册相对于前者更上一层楼,它除了基本的编程风格的规约外,还给出了日志、单元测试、安全、MySQL、工程结构等代码之外的规约,据说是阿里近万名开发同学集体智慧的结晶,相当了得,还是挺值得借鉴一下的。各部分概要如下:

1、编程规约:命名风格、常量、代码格式、OOP、集合处理、并发、控制语句、注释等 2、异常日志:异常处理、日志的命名、保留时间、输出级别、记录信息等 3、单元测试:AIR原则(Automatic,Independent,Repeatable)、单侧的代码目录、目标,单侧的写法,即BCDE原则(Border,Correct,Design,Error) 4、安全规约:权限校验、数据脱敏、参数有效校验、CSRF安全过滤、防重放限制、风控策略等 5、MySQL数据库:建表、索引、SQL语句、ORM映射等 6、工程结构:应用分层、二方库依赖(坐标命名、接口约定、pom配置)、服务器端各项配置(TCP超时、句柄数、JVM参数等)

vieyahn2017 commented 5 years ago

函数参数个数,最后确定不大于6

函数代码行数,最后确定不大于100

函数圈复杂度,最后确定不大于15

vieyahn2017 commented 5 years ago

圈复杂度的概念

Cyclomatic complexity: The number of independent paths through the standard control flow graph.

计算方法:

圈复杂度(CC) =判断条件个数 + 1 关键字: if, else if, for, while, &&, ||, case, catch等。