Android Studio工具篇CheckStyle

一.CheckStyle是什么
CheckStyle 是一款帮助开发人员编写出遵守编码标准的Java代码的开发工具.它的主要任务是执行代码检查(这是一项使人觉得枯燥但是又极其重要的工作.).这使其成为执行编码标准的绝佳工具.
CheckStyle 可以检测源码中的很多问题(比如类设计问题,方法设计问题),同时它还具有检测代码布局和格式化问题的能力,如果你想了解全能CheckStyle到底能干嘛,那么这条链接可能就会你想要的.

Checkstyle 是高度可配置的,几乎支持任何的编码标准,这里提供一个示例,支持Sun Code Conventions, Google Java Style.

道理我都懂,没图说JB:

18行的代码5个告警,生无可恋

你可以在这里看到一个使用CheckStyle 和Maven生成修改建议的报告.

二.CheckStyle配置
CheckStyle使用XML来管理配置项,通过xml您可以指定哪些检测模块要运用到java源文件的代码检测中.
CheckStyle许多模块都是TreeWalker FileSetCheck模块的子模块。TreeWalker通过将每个Java源文件单独转换为抽象语法树,然后将结果传递给每个子模块,以供子模块做进一步分析.

这种情况有点类似于网络数据传输中,数据被逐层拆包解析的过程

Module

  1. 一个基本的配置文件被Checker模块所外包.
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
          "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
          "http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
<module name="Checker">
    ....
</module>

2.CheckStyle是通过module的name属性标识来加载类.这个name的写法有一些讲究.
.根据包限定名称直接加载类(这种写法适用于导入第三方检测模块)

<module name="com.puppycrawl.tools.checkstyle.TreeWalker"/>

.加载一个内置类

<module name="AvoidStarImport"/>

.当内部类中名称以[Check]结尾时,可以简写,例如我要加载"com.puppycrawl.tools.checkstyle.checks.ConstantNameCheck "这个类

<module name="ConstantName"/>

Properties

你可以在 Property Types 了解更多的属性配置信息

Module的Properties属性控制Module如何执行任务,一般来说,Properties都有一个默认值,如果默认值符合您的要求,那么完全没必要去重新为它赋值.而当Properties的默认值无法满足您的要求时,您可要在Module内定义属性元素.并为其重新赋值.

<!--MethodLength模块中的max属性指定方法或者构造函数中允许的最大行数.默认值是150,您可以通过以下方式修改它的值-->
<module name="MethodLength">
    <property name="max" value="60"/>
</module>

模块设置的属性可以被子模块所继承

<!--以下配置片段中,tabWidth=4会作用于TreeWalker及其子模块中-->
<module name="Checker">
    <module name="JavadocPackage"/>
    <module name="TreeWalker">
        <property name="tabWidth" value="4"/>
        <module name="AvoidStarImport"/>
        <module name="ConstantName"/>
        ...
    </module>
</module>

可以使用 ${property_name}表达式来指定module的属性值.

<module name="Header">
    <property name="headerFile" value="${checkstyle.header.file}"/>
</module>

property_name 是命令行属性或ant Checkstyle任务属性,如此,您可以使用属性扩展来重新指定模块属性值,而无需更改配置文档。

property 提供了一个可选的默认属性,当该值中的属性无法解析时使用

<!--当无法获取到${checkstyle.javadoc.severity}的属性值时,severity=error-->
<module name="JavadocMethod">
  <property name="severity"
               value="${checkstyle.javadoc.severity}"
               default="error"/>
</module>

当设置集中式配置文件(例如整个公司的一个文件)以降低配置维护成本时,此功能非常有帮助。 对默认情况下满意的项目可以直接使用该配置文件,但具有特殊需求的单个项目可以灵活调整几个设置以满足其需要,而无需复制和维护整个配置。

Checker

Checker(3.0添加) 是 CheckStyle的根目录,同样Checker也有内置属性,该属性会直接被子Module所继承.

name 说明 类型 默认值 发布版本
basedir string null 3.0
cacheFile 存放已检测为文件信息,防止重复检测 string null 6.16
localeCountry 国家信息 string:空字符串或大写ISO 3166 2字国家代码 Java虚拟机的默认区域设置国家/地区 3.0
localeLanguage 本地语言代号 string:空字符串或小写的ISO 639代码 Java虚拟机的默认语言环境语言 3.0
charset 文件字符编码 String System property "file.encoding" 5.0
fileExtensions 文件扩展名 String Set null 6.3
severity 所有违规的默认严重性级别 Severity error 3.1
haltOnException 如果单个文件在验证期间产生任何类型的异常,是否停止Checkstyle的执行 Boolean true 7.4

TreeWalker

name description type default value since
tabWidth 标签字符('\ t')的展开空间数 用于需要标签宽度的消息和检查,例如LineLength Integer 8 3.0
fileExtensions 文件类型扩展名来标识Java文件。 通常只有在编译之前对Java源代码进行预处理并且原始文件没有扩展名.java时,才需要设置此属性。 String Set java 3.0

TreeWalker模块为Java源文件创建一个语法树,并在树的节点遍历期间调用其子模块(称为Checks).语法树的每个节点都有一个令牌. 在遍历期间访问节点会触发为其令牌配置的所有检查。 例如,如果MethodLength已配置为TreeWalker的子模块,则使用方法或构造函数定义令牌访问节点将触发MethodLength以检查节点代码块的行数。

一些检查,如FileLength和LineLength,直接应用于源文件,不涉及语法树的令牌。 其他Checks Module与触发检查的可配置的令牌集相关联。 例如:

<module name="MethodLength"/>

MethodLength Module默认的token集合是{METHOD_DEF, CTOR_DEF}(方法定义,或者构造函数定义),而当某个节点包含METHOD_DEF或者CTOR_DEF令牌,那么TreeWalker 就会调用MethodLength 执行检查.

您可以使用属性令牌指定检查的特定的令牌.令牌的值是表示Check的令牌的子集的列表,如下面的元素,配置Check MethodLength仅检查方法的行数:

<module name="MethodLength">
    <!--不再包含构造函数-->
    <property name="tokens" value="METHOD_DEF"/>
</module>

如果你要将不同的属性令牌标记应用于同一个Checks Module中,请重写Checks Module.例如下面这样操作.

<module name="MethodLength">
    <property name="tokens" value="METHOD_DEF"/>
</module>
<module name="MethodLength">
    <property name="tokens" value="CTOR_DEF"/>
    <property name="max" value="60"/>
</module>

以上代码片段代表检查方法的长度(无配置则默认是150行),构造方法的长度为60行.

Severity(告警级别)

每一个Checks Module都有告警级别属性,CheckStyle给予的默认属性是Error级别.你可以向下面的代码片段一样,更改它的告警级别:

<module name="Translation">
    <property name="severity" value="warning"/>
</module>

将类型转换 告警级别调至warning级别.

Custom Messages(自定义消息)

从CheckStyle5.0开始,CheckStyle的Checks Module已经被定义成可自定义输出消息.这个功能在检测消息需要引用编码样式文档中的相应部分或默认消息对于开发人员来说是太难以理解的情况下非常有用.

<module name="MemberName">
    <property name="format" value="^m[a-zA-Z0-9]*$"/>
    <message key="name.invalidPattern"
             value="Member ''{0}'' must start with a lowercase ''m'' (checked pattern ''{1}'')."/>
</module>

请注意,消息模式必须是一个有效的java.text.MessageFormat样式模式,因此请注意占位符定义外的花括号。

每个检查配置元素可以具有零个或多个消息元素。 每个检查使用一个或多个不同的消息密钥来记录违规。 如果要自定义某个消息,则需要在消息元素的key属性中指定消息密钥。

Filters(过滤器)

Checker模块具有一组过滤器子模块,用于过滤审核事件,包括Checks发出的错误消息。 过滤器可以接受或拒绝审核事件。 如果所有过滤器都接受审核事件,则Checker会报告事件。 如果任何Filter拒绝事件,则Checker不会报告事件。 有关更多信息,请访问过滤器页面。

执行前文件过滤器(什么鬼)

检查器模块具有“执行前文件过滤器”子模块,以过滤文件被该实用程序处理。 执行前文件过滤器可以按其名称接受或拒绝文件。 如果所有执行文件过滤器都接受文件,则Checker将处理并验证文件。 如果任何执行前文件过滤器拒绝文件,则Checker会跳过该文件,并且行为类似于它不存在。 有关更多信息,请访问文件过滤器页面

AuditListeners(审核监听器)

除了文本或XML输出的审核记录之外,Checker还可以拥有处理审核事件的自定义AuditListener。 为了使用自定义侦听器,为侦听器及其属性添加一个Checker子模块。 例如,要配置Checker,以便它使用自定义侦听器VerboseListener将审核消息打印到名为“audit.txt”的文件中,请在配置文件中包含以下模块:

<module name="com.mycompany.listeners.VerboseListener">
    <property name="file" value="audit.txt"/>
</module>

Packages

Checkstyle根据模块元素的名称加载模块类,并在搜索可加载类时自动将预先指定的包前缀附加到该名称。 默认情况下,Checkstyle应用包com.puppycrawl.tools.checkstyle,com.puppycrawl.tools.checkstyle.filters和com.puppycrawl.tools.checkstyle.checks以及com.puppycrawl.tools.checkstyle的任何子包。
要指定要应用的其他包,请创建名为checkstyle_packages.xml的XML文件,并将该文件提供到包含您的自定义检查的.jar的根目录中。

请注意,通过命令行选项或Ant Checkstyle任务的属性提供包命名XML文档的支持已经在Checkstyle 5.0版本上删除。

包名称XML文档指定包名称列表。 以下是软件包名称XML文档的示例程序包com.puppycrawl.tools.checkstyle和com.puppycrawl.tools.checkstyle.checks:

<checkstyle-packages>
  <package name="com.puppycrawl.tools.checkstyle">
    <package name="checks"/>
  </package>
</checkstyle-packages>

例如,要让Checkstyle能够使用包com.mycompany.checks中的模块,请创建下面的XML文件,并将该文件放入包含自定义检查模块的jar文件的根目录下。 该XML文件必须完全命名为checkstyle_packages.xml:

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

    <!DOCTYPE checkstyle-packages PUBLIC
    "-//Puppy Crawl//DTD Package Names 1.0//EN"
    "http://checkstyle.sourceforge.net/dtds/packages_1_0.dtd">

<checkstyle-packages>
  <package name="com.mycompany.checks"/>
</checkstyle-packages>

现在你可以在配置文件中配置一个包com.mycompany.checks的模块,比如说com.mycompany.checks.MethodLimitCheck,它有一个简化的写法:

<module name="MethodLimit"/>

XML Structure(CheckStyle 的xml语法结构)
配置XML文档的以下DTD指定模块及其属性的层次结构:

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

<!ELEMENT module (module|property)*>
<!ATTLIST module name NMTOKEN #REQUIRED>

<!ELEMENT property EMPTY>
<!ATTLIST property
        name NMTOKEN #REQUIRED
        value CDATA #REQUIRED
>

Checkstyle在加载文档时验证配置XML文档。 要根据上述配置DTD进行验证,请在配置XML文档中包含以下文档类型声明:

<!DOCTYPE module PUBLIC
    "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
    "http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">

Checkstyle还严格执行XML声明的编码属性。 如果Checkstyle拒绝配置文档的编码,请更正encoding属性的值,或者完全删除编码属性。

有关配置XML文档的完整示例,请检查检查Sun编码约定的文档docs / sun_checks.xml。

这是一个包名称XML文档的DTD:

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

<!ELEMENT checkstyle-packages (package)*>

<!ELEMENT package (package)*>
<!ATTLIST package name NMTOKEN #REQUIRED>

Checkstyle还会在加载文档时验证包名XML文档。 要根据上述软件包名称DTD进行验证,请在软件包名称XML文档中包含以下文档类型声明:

<!DOCTYPE checkstyle-packages PUBLIC
"-//Puppy Crawl//DTD Package Names 1.1//EN"
"http://checkstyle.sourceforge.net/dtds/packages_1_1.dtd">

这是一个抑制XML文档的DTD:

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

<!ELEMENT suppressions (suppress*)>

<!ELEMENT suppress EMPTY>
<!ATTLIST suppress files CDATA #REQUIRED
                   checks CDATA #IMPLIED
                   id CDATA #IMPLIED
                   lines CDATA #IMPLIED
                   columns CDATA #IMPLIED>

您可要在这里找到所有支持的Check Module类型.

========================================================================
Demo展示:

<?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">

<!--Create by fengwenhua 2017年11月2日13:32:57-->

<!--这是CheckStyle根目录-->
<module name="Checker">
    
    <property name="charset" value="UTF-8"/>
    <property name="severity" value="warning"/>

    <!--该节点可以把Java源文件的内容解析成语法树,并将语法树内容分发给子Module进行进一步的检测-->
    <module name="TreeWalker">
        <!--检查[标识符名称]中的缩写(连续大写字母)的长度,它也允许强制骆驼命名。(需要父Module TreeWalker 支持)-->
        <module name="AbbreviationAsWordInName">
            <!--当变量定义或类定义时,该检测有效-->
            <property name="tokens" value="VARIABLE_DEF,CLASS_DEF"/>
            <!--一般来说,静态常量都是大写 忽略该检测-->
            <property name="ignoreStatic" value="true"/>
            <!--最多可以连续打印1个大写字母,MyTest正确,MyTEst错误-->
            <property name="allowedAbbreviationLength" value="0"/>
            <!--必须跳过检查的缩写列表。缩写列表应该用逗号隔开,不允许有空格。-->
            <property name="allowedAbbreviations" value="XML,URL"/>
        </module>

        <!--验证抽象类的标识符-->
        <module name="AbstractClassName">
            <!--抽象类以Abstract开头-->
            <property name="format" value="^Abstract.+$"/>
            <!--匹配名称的类的抽象修饰符丢失是否需要告警:默认就是false,因此可以不写-->
            <property name="ignoreModifier" value="false"/>
        </module>

        <!--匿名内部类最大长度值:太过庞大的匿名内部类在后期维护会相当困难,因此需要保证让其短小精悍-->
        <module name="AnonInnerLength">
            <property name="max" value="100"/>
        </module>
        <!--数组定义风格:C风格(String args[])还会Java风格(String[] args)-->
        <module name="ArrayTypeStyle">
            <property name="javaStyle" value="true"/>
        </module>

         <!--
        内联条件很难阅读,所以使用编码标准禁止它(比如三目运算符)
        <module name="AvoidInlineConditionals"/>
        -->
        <!--是否允许*号导包-->
        <module name="AvoidStarImport">
            <!--被允许*号导包-->
            <property name="excludes" value="java.io,java.net,java.lang.Math"/>
            <!--是否可以import java.util.*; 这样导包-->
            <property name="allowClassImports" value="false"/>
            <!--是否可以import static org.junit.Assert.*;静态导包-->
            <property name="allowStaticMemberImports" value="true"/>
        </module>

        <!--检测无效导包-->
        <module name="UnusedImports"/>
        <!--检测是否有不必要的括号-->
        <module name="UnnecessaryParentheses"/>

        <!--接口名称定义,以I开头-->
        <module name="TypeName">
            <property name="format" value="^I_[a-zA-Z0-9]*$"/>
            <property name="tokens" value="INTERFACE_DEF"/>
        </module>

        <!--检测TODO-->
        <module name="TodoComment">
            <property name="format" value="TODO"/>
        </module>
    </module>    
  
</module>

参考链接:
CheckStyle官网

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容

  • 1、在android studio中安装checkstyle插件。 具体操作见上图。安装完之后见下图 底栏会多一个...
    nmssdmf阅读 3,637评论 0 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • 本文主要介绍以下内容:(1)CheckStyle详细使用(2)如何定制专属CheckStyle检查规则(3)如何定...
    freddyyao阅读 14,783评论 11 16
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,778评论 6 342
  • 最近和同事聊天,聊到了最不愿意聊到的话题中。 就叫他同事B吧,在之前的闲聊中,同事B得知我在大学中还未谈过恋爱...
    小霏铃子阅读 531评论 0 0