Checkstyle案例

wen java案例 5

本文目录导读:

Checkstyle案例

  1. 项目结构
  2. Checkstyle配置文件 (checkstyle.xml)
  3. 具有违规的示例代码
  4. Maven配置 (pom.xml)
  5. 运行Checkstyle
  6. Checkstyle输出示例
  7. 修正后的代码参考

我将为您提供一个完整的Checkstyle配置和违规案例演示。

项目结构

checkstyle-demo/
├── pom.xml
├── checkstyle.xml
├── src/
│   └── main/
│       └── java/
│           └── com/
│               └── example/
│                   ├── UserService.java
│                   └── User.java

Checkstyle配置文件 (checkstyle.xml)

<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
    "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
    "https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
    <property name="charset" value="UTF-8"/>
    <property name="severity" value="error"/>
    <property name="fileExtensions" value="java"/>
    <!-- 排除文件 -->
    <module name="BeforeExecutionExclusionFileFilter">
        <property name="fileNamePattern" value="module\-info\.java$"/>
    </module>
    <!-- 检查文件中的Tab键 -->
    <module name="FileTabCharacter">
        <property name="eachLine" value="true"/>
    </module>
    <!-- 文件长度 -->
    <module name="FileLength">
        <property name="max" value="2000"/>
    </module>
    <module name="TreeWalker">
        <!-- Javadoc 注释检查 -->
        <module name="JavadocType">
            <property name="scope" value="public"/>
        </module>
        <module name="JavadocMethod">
            <property name="scope" value="public"/>
            <property name="allowMissingReturnType" value="false"/>
            <property name="allowedAnnotations" value="Override"/>
        </module>
        <!-- 命名规范 -->
        <module name="ClassTypeParameterName">
            <property name="format" value="^[A-Z][A-Z0-9]*$"/>
        </module>
        <module name="ConstantName"/>
        <module name="LocalFinalVariableName"/>
        <module name="LocalVariableName"/>
        <module name="MemberName">
            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
        </module>
        <module name="MethodName"/>
        <module name="PackageName"/>
        <module name="ParameterName">
            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
        </module>
        <module name="TypeName"/>
        <!-- 代码块检查 -->
        <module name="LeftCurly">
            <property name="option" value="eol"/>
        </module>
        <module name="RightCurly">
            <property name="option" value="same"/>
        </module>
        <module name="NeedBraces"/>
        <!-- 空格检查 -->
        <module name="EmptyLineSeparator">
            <property name="allowNoEmptyLineBetweenFields" value="true"/>
        </module>
        <module name="WhitespaceAround">
            <property name="allowEmptyTypes" value="true"/>
        </module>
        <!-- 导入检查 -->
        <module name="AvoidStarImport"/>
        <module name="UnusedImports"/>
        <module name="RedundantImport"/>
        <!-- 代码复杂度检查 -->
        <module name="CyclomaticComplexity">
            <property name="max" value="10"/>
        </module>
        <module name="JavaNCSS">
            <property name="methodMaximum" value="50"/>
        </module>
        <!-- 代码格式检查 -->
        <module name="LineLength">
            <property name="max" value="120"/>
            <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://"/>
        </module>
        <module name="Indentation">
            <property name="basicOffset" value="4"/>
            <property name="braceAdjustment" value="0"/>
            <property name="caseIndent" value="4"/>
        </module>
        <!-- 其他检查 -->
        <module name="MultipleVariableDeclarations"/>
        <module name="ArrayTypeStyle"/>
        <module name="MissingSwitchDefault"/>
        <module name="FallThrough"/>
        <module name="EmptyStatement"/>
        <module name="EqualsHashCode"/>
        <module name="SimplifyBooleanExpression"/>
        <module name="SimplifyBooleanReturn"/>
        <module name="StringLiteralEquality"/>
    </module>
</module>

具有违规的示例代码

User.java (包含违规)

package com.example;
import java.util.*;
import java.math.BigDecimal;
        import java.util.ArrayList;
/**
 * 用户实体
 * @author
 */
public class user {  // 违规1: 类名小写
    private String name;
    private int age;
    private String email;
    public String publicField;  // 违规2: public字段
    // 违规3: 缺少Javadoc
    public user() {
        name = "unknown";
    }
    // 违规4: 方法命名不规范
    public void getuserinfo() {  // 应为 camelCase getUserInfo
        String user_name = "test";  // 违规5: 局部变量命名
        INTEGER count = 0;  // 违规6: 使用包装类型作为基本类型
        for(int i = 0; i < 5; i++) {  // 违规7: 缺少空格
            if(count == 1)
            {
                System.out.println("one");  // 违规8: 花括号位置
            } else {
                System.out.println(count);
            }
        }
        // 违规9: 魔法数字
        int days = 365;
        // 违规10: 简化布尔表达式
        if(count > 0 == true) {
            System.out.println("positive");
        }
    }
    // 违规11: 方法过长且复杂度高
    public void complexMethod(int a, int b, int c) {
        if(a > 0) {
            if(b > 0) {
                if(c > 0) {
                    if(a > b) {
                        if(b > c) {
                            if(a > c) {
                                System.out.println("complex1");
                            } else {
                                System.out.println("complex2");
                                if(a == c) {
                                    System.out.println("complex3");
                                }
                            }
                        } else {
                            System.out.println("complex4");
                            if(c > a) {
                                System.out.println("complex5");
                            }
                        }
                    } else {
                        System.out.println("complex6");
                        if(c > a) {
                            if(c > b) {
                                System.out.println("complex7");
                            } else {
                                if(b > a) {
                                    System.out.println("complex8");
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    // 违规12: 缺少默认switch
    public String getDayType(int day) {
        String type;
        switch(day) {
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
                type = "工作日";
                break;
            case 6:
            case 7:
                type = "周末";
                break;
        }
        return type;
    }
}

Maven配置 (pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>checkstyle-demo</artifactId>
    <version>1.0.0</version>
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <checkstyle.version>9.3</checkstyle.version>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-checkstyle-plugin</artifactId>
                <version>3.1.2</version>
                <configuration>
                    <configLocation>checkstyle.xml</configLocation>
                    <consoleOutput>true</consoleOutput>
                    <failsOnError>true</failsOnError>
                    <linkXRef>false</linkXRef>
                </configuration>
                <executions>
                    <execution>
                        <phase>verify</phase>
                        <goals>
                            <goal>check</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

运行Checkstyle

# 运行Checkstyle检查
mvn checkstyle:check
# 生成Checkstyle报告
mvn checkstyle:report
# 完整构建时执行检查
mvn verify

Checkstyle输出示例

[INFO] There is 1 error reported:
[INFO] 
[INFO] Starting audit...
[ERROR] User.java:8:1: Type name 'user' must match pattern '^[A-Z][a-zA-Z0-9]*$'. [TypeName]
[ERROR] User.java:11: Type Javadoc comment is missing an @author tag. [JavadocType]
[ERROR] User.java:12:5: Variable 'publicField' must be private and have accessor methods. [VisibilityModifier]
[ERROR] User.java:16:5: Missing a Javadoc comment. [JavadocMethod]
[ERROR] User.java:21:17: Method name 'getuserinfo' must match pattern '^[a-z][a-zA-Z0-9]*$'. [MethodName]
[ERROR] User.java:22:13: Local variable name 'user_name' must match pattern '^[a-z][a-zA-Z0-9]*$'. [LocalVariableName]
[ERROR] User.java:23:13: Local variable name 'count' must match pattern '^[a-z][a-zA-Z0-9]*$'. [LocalVariableName]
[ERROR] User.java:25:14: 'for' is not followed by whitespace. [WhitespaceAround]
[ERROR] User.java:28:17: '{' should be on the previous line. [LeftCurly]
[ERROR] User.java:31:13: '}' should be on the same line. [RightCurly]
[ERROR] User.java:33:13: Magic number '365' - use a constant. [MagicNumber]
[ERROR] User.java:37:22: Avoid use of equality operator '==' with boolean expression. [SimplifyBooleanExpression]
[ERROR] User.java:72:9: Switch without 'default' clause. [MissingSwitchDefault]
[ERROR] User.java:6:1: Unused import - java.util.ArrayList. [UnusedImports]
[ERROR] User.java:5:1: Using the '.*' form of import should be avoided - java.util.*. [AvoidStarImport]
[ERROR] User.java:7:1: Redundant import from the same package - java.util.ArrayList. [RedundantImport]

修正后的代码参考

package com.example;
import java.util.HashMap;
import java.util.Map;
/**
 * 用户实体
 *
 * @author YourName
 * @version 1.0
 */
public class User {
    private static final int DAYS_IN_YEAR = 365;
    private static final int MAX_COMPLEXITY = 10;
    private String name;
    private int age;
    private String email;
    /**
     * 默认构造函数
     */
    public User() {
        this.name = "unknown";
        this.age = 0;
        this.email = "";
    }
    /**
     * 获取用户信息
     *
     * @return 用户信息字符串
     */
    public String getUserInfo() {
        String userName = "test";
        int userAge = 18;
        for (int i = 0; i < userName.length(); i++) {
            if (userAge > MAX_COMPLEXITY) {
                System.out.println("Age is large");
            } else {
                System.out.println(userName.indexOf(userName.charAt(i)));
            }
        }
        int days = DAYS_IN_YEAR;
        return userName + " " + userAge + " " + days;
    }
    /**
     * 获取星期类型
     *
     * @param day 日期
     * @return 类型描述
     */
    public String getDayType(int day) {
        String type;
        switch (day) {
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
                type = "工作日";
                break;
            case 6:
            case 7:
                type = "周末";
                break;
            default:
                type = "无效日期";
                break;
        }
        return type;
    }
}

这个案例展示了Checkstyle的主要功能:

  1. 命名规范 - 类名、方法名、变量名
  2. 代码格式 - 缩进、空格、行长度
  3. Javadoc要求 - 必须为公共方法添加注释
  4. 复杂度控制 - 限制圈复杂度
  5. 导入管理 - 避免通配符导入、检查未使用的导入
  6. 最佳实践 - 避免魔法数字、简化布尔表达式

通过定期运行Checkstyle,可以确保代码质量和一致性,使团队协作更加顺畅。

抱歉,评论功能暂时关闭!