Checkstyle:整洁你的代码

 内容

  • Checkstyle简介
  • 下载
  • Checkstyle的几种使用方式
    • 1) 与Ant结合使用
    • 2) 通过CLI使用
    • 3)在IDE上使用插件
    • 4)在Maven上使用插件
  • Checkstyle配置
    • 配置文件结构
      • Property 值分类
      • Module分类
      • Checker属性
      • Serverity属性
      • Message自定义
    • TreeWalker
    • Filters
      • ServeritymatchFileter
    • Checker分类说明

 

Checkstyle简介

         Checkstyle是一个帮助程序员写出标准格式代码的开发辅助工具。使用它会让代码更加简洁、漂亮。

         Checkstyle是高可配的并且支持多种代码风格。使用它可以帮你找出Class\Method设计中的问题,同时也可以帮你找出代码布局和格式上的问题。

 

下载

有两种方式下载:

https://sourceforge.net/projects/checkstyle/files/checkstyle/

使用Maven下载:

<dependency>

    <groupId>com.puppycrawl.tools</groupId>

    <artifactId>checkstyle</artifactId>

    <version>6.16.1</version>

</dependency>

 

 

Checkstyle的几种使用方式

Checkstyle有多种使用方式:

1)  与Ant结合使用

2)  通过CLI来使用

3)  作为Maven插件来使用

4)  Hudson集成

 

下面就针对这几种方式分别说明:

 

1)与Ant结合使用

相关文档:

http://checkstyle.sourceforge.net/anttask.html

 

 

 

2)通过CLI上使用Checkstyle

http://checkstyle.sourceforge.net/cmdline.html

 

命令行使用方式:

java -D<property>=<value>  \

     com.puppycrawl.tools.checkstyle.Main \

     -c <configurationFile> \

     [-f <format>] [-p <propertiesFile>] [-o <file>] \

     [-t | --tree] [-T | --treeWithComments] [-v] \

     file...

 

 

 

3)Checkstyle作为Eclipse插件使用

插件下载地址:

https://sourceforge.net/projects/eclipse-cs/files/latest/download

 

下载安装后,重启Eclipse。

在文件夹右键菜单中可以看到:

 

使用Check Code with Checkstyle就可以进行代码检查了。查检后会在代码中不合理的地址标出来。使用Clear Checkstyle就可以将这些标识去掉。

在Preferences下可以对checkstyle进行配置:Eclipse插件下默认使用的是google的checkstyle配置。

 

 

4) 通过maven插件使用

 

插件的基本配置是:

<plugin>

    <groupId>org.apache.maven.plugins</groupId>

    <artifactId>maven-checkstyle-plugin</artifactId>

    <version>2.17</version>

</plugin>

 

 

2.17版本的checkstyle插件使用了Checkstyle-6.11.2.jar,对JDK的要求是JDK7。

在jar包中内置了google、sun的checks.xml

 

插件包含3个goal,分别是:

·chechstyle :这是一个report goal。用于执行对代码分析检查。会生成一个分析检查的报告。

·checkstyle-aggregate:这是一个report goal。用于执行对代码分析检查,并将结果汇总,最后产生一个HTML报告。

·check这是一个build goal。用于对代码分析检查,并在console上输出检查结果。

 

例如:

 

 

Checkstyle 配置

         Checkstyle如何对代码进行检查,全部都要依赖于它的配置文件,所以如何配置才能检查出代码中的不合格的地方,也不能让它过多的报一些不认为是错误的格式,这些就非常的重要了。所以需要对它的配置文件要非常的了解才可以。

 

配置文件的结构

Module是一个XML文件,必须遵守一定的格式:

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

<!DOCTYPE module PUBLIC

          "-//Puppy Crawl//DTD Check Configuration 1.3//EN"

          "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">

<module name=”Checker”>

<module .../>

<module .../>

….

</module>

 

这个配置文件在使用Checkstyle执行代码检查时会加载使用。Checkstyle在设计上分模块设计的。它的配置文件中,也是由一系列的module元素组成的,每个module都有一个name属性,用于对module进行区分。所以name是唯一标识。其中根元素的name属性值是Checker,是第一级。

<module/>的name属性其实一个类的名称。在配置name属性时,可以是类全名,也可以是类名。

         可以为module指定相应的property。这些property都是有默认值的。Property的定义要通过为<module />元素指定子元素<property /> 来完成。<property />可以配置name,value那个attribute。例如:

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

此外,父module的property可以被子module继承。

 

Property值分类

         之前说了可以为<module />指定<property />,因为每种<module />的设计是不一样的,所以它的不同的<property/>的值可以不同类型的。根据属性值的不同,可以将<property>的值类型分为下列几类:

 

·Integer :属性是一个整数

例如:<property name=”name1” value=”3”/>

·String:属性是一个字符串

例如:<property name="severity" value="warning"/>

·Boolean:属性是一个布尔值

它的值如果是:yes,true,on时,表示为true;反之no,false,off表示false。

·StringSet:属性值是一个字符串集合

在设置值时,用,分隔。例如:

<property name="tokens" value="DIV_ASSIGN,PLUS_ASSIGN"/>
也可以用下面的替换:
<property name="tokens" value="DIV_ASSIGN"/>
<property name="tokens" value="PLUS_ASSIGN"/>
·IntSet:属性值是一个整数集合

在设置值时,用,分隔。例如:

<property name="tokens" value="42,666"/>

也可以用下面的替换:

<property name="tokens" value="42"/>
<property name="tokens" value="666"/>
·Regexp:值是一个正则表达式

正则表达式的取值,可以参考java.util.Pattern的javadoc。

·ParenPad:代码与()的内间距

有两个值:

nospace 表示没有内间距。例如: method(a, b)

space:表示有内间距。例如:method( a, b )

·WrapOp:换行处的操作符位置

Option

Definition

nl

The token must be on a new line. For example:

    someVariable = aBigVariableNameToMakeThings + "this may work"

                   + lookVeryInteresting;

           

eol

The token must be at the end of the line. For example:

    someVariable = aBigVariableNameToMakeThings + "this may work" +

                   lookVeryInteresting;

           

 

·Block:对代码块的要求

 

Option

Definition

text

Require that there is some text in the block. For example:

    catch (Exception ex) {

        // This is a bad coding practice

    }

           

stmt

Require that there is a statement in the block. For example:

    finally {

        lock.release();

    }

           

 

 

·Lcurly :左花括号的位置

 

Option

Definition

eol

The brace must always be on the end of the line. For example:

    if (condition) {

        ...

           

nl

The brace must always be on a new line. For example:

    if (condition)

    {

        ...

           

nlow

If the brace will fit on the first line of the statement, then apply eol rule. Otherwise apply the nl rule. nlow is a mnemonic for "new line on wrap". For the example above Checkstyle will enforce:

    if (condition) {

        ...

           

But for a statement spanning multiple lines, Checkstyle will enforce:

    if (condition1 && condition2 &&

        condition3 && condition4)

    {

        ...

           

 

·Rcurly:右花括号的位置。

 

same

The brace should be on the same line as the next part of a multi-block statement (one that directly contains multiple blocks: if/else-if/else or try/catch/finally).

Examples:

    // try-catch-finally blocks

    try {

        ...

    } catch (Exception ex) { // this is OK

        ...

    } finally { // this is OK

        ...

    }

 

    try {

        ...

    } // this is NOT OK, not on the same line as the next part of a multi-block statement

    catch (Exception ex) {

          ...

    } // this is NOT OK, not on the same line as the next part of a multi-block statement

    finally {

          ...

    }

alone

The brace must be alone on the line. For example:

    try {

        ...

    }

    finally {

        ...

    }

           

alone_or_singleline

The brace must be alone on the line, yet single-line format of block is allowed. For example:

    // Brace is alone on the line

    try {

        ...

    }

    finally {

        ...

    }

 

    // Single-line format of block

    public long getId() { return id; }

                 

 

·Serverity 检查结果级别控制

可取值有:ignore、info、warning、error。

Ignore表示忽略,即不会被report。

 

 

 

·ImportOrder import语句的顺序

 

Option

Definition

top

All static imports are at the top. For example:

    import static a.b.C.*;

    import static x.y.Z.*;

 

    import a.b.D;

    import x.y.Z;

above

All static imports are above the local group. For example:

    import static a.b.C.*;

    import a.b.D;

 

    import static x.y.Z.*;

    import x.y.Z;

inflow

All static imports are processed like non static imports. For example:

    import static a.b.C.*;

    import a.b.D;

 

    import x.y.Z;

    import static x.y.Z.*;

under

All static imports are under the local group. For example:

    import a.b.D;

    import static a.b.C.*;

 

    import x.y.Z;

    import static x.y.Z.*;

bottom

All static imports are at the bottom. For example:

    import a.b.D;

    import x.y.Z;

 

    import static a.b.C.*;

    import static x.y.Z.*;

 

 

·AnnotationStyle 注解元素的风格

可能取值:

Option

Definition

expanded

The expanded version is sometimes referred to as "named parameters" in other languages. Example:

@SuppressWarnings(value={"unchecked","unused",})

compact

This style can only be used when there is an element called 'value' which is either the sole element or all other elements have default values. Examples:

@SuppressWarnings({"unchecked","unused",})

and:

@SuppressWarnings("unchecked")

compact_no_array

It is similar to the compact style but single value arrays are flagged. With annotations a single value array does not need to be placed in an array initializer. This style can only be used when there is an element called 'value' which is either the sole element or all other elements have default values. Example:

@SuppressWarnings("unchecked")

ignore

Anything goes.

 

注解中的括号:

Option

Definition

always

Example:

@Deprecated()

never

Example:

@Deprecated

ignore

Anything goes.

 

注解中的逗号:

Option

Definition

always

Example:

@SuppressWarnings(value={"unchecked","unused",})

never

Example:

@SuppressWarnings(value={"unchecked","unused"})

ignore

Anything goes.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Module分类

 

二级元素所代表的那些modules,主要分为三类:

·FileSetChecks 这些modules用于对file进行检查,发现问题后会报出错误消息。

·Filters 这些模块用于过滤审核事件和错误消息。

·AuditListeners 报告可接收的事件。

 

示例:

 

<module name="Checker">
    <module name="JavadocPackage"/>
    <module name="TreeWalker">
        <module name="AvoidStarImport"/>
        <module name="ConstantName"/>
        <module name="EmptyBlock"/>
    </module>

</module>    

在这个典型的配置文件中,根moudle Checker 有2个FileSetChecker类别的module: JavadocPackage, TreeWalker。

其中JavadocPackage是要求指定的java package下必须得有package-info.java文件。通常这是没有必要的,所以这个规则一般不会使用。

而ThreeWalker下面有三个module,这三个module的作用是:

·AvoidStarImport  import语句中不能出现.*

·ConstantName 常量名称检查

·EmptyBlock 检查是否有空的代码块。

 

 

 

 

Checker的属性

 

name

description

type

default value

basedir

base directory name; stripped off in messages about files

string

null

cacheFile

caches information about files that have checked OK; used to avoid repeated checks of the same files

string

null (no cache file)

localeCountry

locale country for messages

string: either the empty string or an uppercase ISO 3166 2-letter code

default locale country for the Java Virtual Machine

localeLanguage

locale language for messages

string: either the empty string or a lowercase ISO 639 code

default locale language for the Java Virtual Machine

charset

name of the file charset

String

System property "file.encoding"

fileExtensions

file extensions that are accepted

   

 

<module name="Checker">
    <property name="basedir" value="src/checkstyle"/>
    <property name="cacheFile" value="target/cachefile"/>
    <property name="localeCountry" value="DE"/>
<property name="localeLanguage" value="de"/>
<property name="charset" value="UTF-8"/>
 
    <module name="JavadocPackage"/>
    <module name="TreeWalker">
        ...
    </module>
</module>

 

 

Serverity属性

         每个checker都会有一个serverity属性。用于指定当代码违反相关module指定的规则时,给出哪种级别的错误。默认值是error,通常我们会将其改为warning。

例如:

<module name="Checker">

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

<module name="JavadocPackage"/>

</module>

 

Message 自定义消息

         之前已经说了,当检查到不符合规则时,有错误消息的。所以Checkstyle为每一种检查都指定了默认的消息。有时我们希望使用的是自定义的消息,Checkstyle也提供了为种功能。

Message的自定义可以通过在每个checker module下指定<message>属性元素来完成。例如:

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

 

 

 

 

 

TreeWalker

 

FileSetChecker moudle中的许多module都是TreeWalker module的子模块。

 

TreeWalker的工作原理是:将每个java source 文件转换成一个抽象的语法树,然后使用TreeWalker下的子modules轮流对这个语法树进行检查。

但是TreeWalker下也有一些checker module是不会调用语法树的。例如FileLength,LineLength。

 

 

name

description

type

default value

tabWidth

number of expanded spaces for a tab character ('\t'); used in messages and Checks that require a tab width, such as LineLength

integer

8

fileExtensions

file type extension to identify Java files. Setting this property is typically only required if your Java source code is preprocessed before compilation and the original files do not have the extension .java

String Set

java

 

 

<module name="Checker">
    <module name="TreeWalker">
        <property name="tabWidth" value="4"/>
        <property name="fileExtensions" value="java"/>
 
        ...
    </module>
</module>

 

 

 

 

 

 

Filters

         每个Filter都会有一个Filters集合,用于对Check的审计事件(也可以说是检查不合格事件)进行过滤。如果filter接受了这个事件,应会报告出来,如果不接受这个事件,就不会报出来。Filter的配置是在每个check module下的子module。

 

·ServerityMatchFilter

根据每个check module的Serverity属性来判断是否接受。

 

name

description

type

default value

severity

the severity level of this filter

severity

error

acceptOnMatch

If acceptOnMatch is true,

then the filter accepts an audit

 event if and only if

there is a match between

the event's severity level and property severity.

If acceptOnMatch is false,

then the filter accepts an audit event if and only if

 there is not a match between the event's severity level and property severity.

boolean

true

 

默认情况下,当filter中指定的serverity与checker的serverity匹配(值相同)时,接收这个检查结果。

 

例如:

<module name="SeverityMatchFilter">
  <property name="severity" value="warning"/>
  <property name="acceptOnMatch" value="true"/>
</module>          

这个例子就是,当出现warning时,就报告敬告信息。

 

 

 

name

description

type

default value

offCommentFormat

comment pattern to trigger filter to begin suppression

regular expression

CHECKSTYLE\:OFF

onCommentFormat

comment pattern to trigger filter to end suppression

regular expression

CHECKSTYLE\:ON

checkFormat

check pattern to suppress

regular expression

.* (all checks)

messageFormat

message pattern to suppress

regular expression

none

checkCPP

whether to check C++ style comments (//)

boolean

true

checkC

whether to check C style comments (/* ... */)

boolean

true

 

 

 

Checker分类说明

 

可以把Checker分为下面几个类别:

·Annotations

·Block Checks

·Coding

·Headers

·Imports

·Javadoc Comments

·Metrics

·Miscellaneous

·Modifiers

·Naming

·Regexp

·Size Violations

·Whitespace

 具体内容参考:http://checkstyle.sourceforge.net/checks.html

 

你可能感兴趣的:(Checkstyle:整洁你的代码)