1. 配置基
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
2. 指定项目的JDK版本
使用 Maven 构建项目时,建议最好指定编译 JDK 版本。首先,因为 Maven 默认的编译 JDK 版本一般比较低,目前默认的设置为1.5,默认用此版本,而不是根据你项目中指定的 JDK 版本编译。其次,项目代码上线通常是由打包机编译打包,然后部署到测试环境最后部署到生产的,而打包机上的 Maven 默认使用什么编译 JDK 版本我们是不确定的。
<build>
<pluginManagement>
<plugins>
<plugin>
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-compiler-plugin -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<!-- 截止到写文章位置,该版本最新是3.8.1。可以缺省,使用默认值也可,但不建议。 -->
<version>3.8.1</version>
<configuration>
<!-- 源代码使用的 JDK 版本 -->
<source>${java.version}</source>
<!-- 需要生成的目标 class 文件的编译版本 -->
<target>${java.version}</target>
<!-- 字符集编码 -->
<encoding>${project.build.sourceEncoding}</encoding>
<compilerVersion>${java.version}</compilerVersion>
<!-- 是否跳过测试 -->
<skipTests>true</skipTests>
<showWarnings>true</showWarnings>
<!-- 编译器使用的初始内存 -->
<meminitial>128m</meminitial>
<!-- 编译器使用的最大内存 -->
<maxmem>512m</maxmem>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
以上配置方法只针对某个项目生效,有时候在本地开发是不想重复配置,也可以配置 Maven 默认的编译 JDK 版本。在 Maven 安装目录中找到 conf/settings.xml 文件,在 <profiles>
标签下添加配置:
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
3. 添加 Checkstyle 检查
团队中每个人写代码的风格迥异,为了让大家提交上来的代码具有统一的风格,光靠嘴上说统一是没用的,还需借助工具。Checkstyle 就是这样一个工具,可以做代码格式检查。它同时还提供 maven-checkstyle-plugin
插件,集成到我们的 maven 项目中,执行构建时自动做代码风格检查,如果有不规范的直接构建失败,这样保证出口的代码都是符合代码规范的。
3.1 编写规范配置文件
Checkstyle 可以配置很多规则,有些是必要的,有些我感觉太严格了。具体每条规则什么含义可以参考:https://checkstyle.org/checks.html,下面是我常用的配置示例:
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd">
<!-- 以下所有 module 指定的name,没有添加property的配置,都是选择官方网站上默认的配置参数。-->
<module name="Checker">
<!-- 字符集编码 -->
<property name="charset" value="UTF-8"/>
<!-- 违规级别 -->
<property name="severity" value="error"/>
<!-- 需要检查的文件扩展名 -->
<property name="fileExtensions" value="java, properties, xml"/>
<!-- 文件是否包含制表符 -->
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
</module>
<!-- 行长度 -->
<module name="LineLength">
<property name="fileExtensions" value="java"/>
<property name="max" value="200"/>
<property name="ignorePattern" value="^implements.*|^extends.*|^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>
<!-- property 文件中是否有相同的 key -->
<module name="Translation"/>
<!-- Java 源文件并定义一些适用于检查此类文件的一些属性 -->
<module name="TreeWalker">
<!--对方法的注释,这里表示必须注释每一个方法,可以不对方法里面的参数进行注释 -->
<module name="JavadocMethod">
<!-- 可以检查的方法的范围,例如:public只能检查public修饰的方法,private可以检查所有的方法 -->
<property name="scope" value="puplic"/>
<property name="allowUndeclaredRTE" value="true"/>
<!-- 是否忽略对参数注释的检查 -->
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingJavadoc" value="false"/>
<!-- 是否忽略对throws注释的检查 -->
<property name="allowMissingThrowsTags" value="false"/>
<!-- 是否忽略对return注释的检查 -->
<property name="allowMissingReturnTag" value="false"/>
<!-- 是否允许get/set 方法没有注释-->
<property name="allowMissingPropertyJavadoc" value="true"/>
</module>
<!-- 外部类型名称和文件名是否匹配 -->
<module name="OuterTypeFilename"/>
<!--包名的命名规范 -->
<module name="PackageName" />
<!-- 类名的命名规范-->
<module name="TypeName"/>
<module name="MemberName"/>
<module name="ParameterName"/>
<module name="LambdaParameterName"/>
<module name="CatchParameterName"/>
<module name="LocalVariableName"/>
<module name="ClassTypeParameterName"/>
<module name="MethodTypeParameterName"/>
<module name="InterfaceTypeParameterName"/>
<!-- 方法名的命名规范-->
<module name="MethodName"/>
<!-- 对常量的命名规范-->
<module name="ConstantName"/>
<!-- 静态变量的命名规范-->
<module name="StaticVariableName"/>
<!-- 必须导入类的完整路径,即不能使用*导入所需的类 -->
<module name="AvoidStarImport"/>
<!-- 检查是否导入的包没有使用 -->
<module name="UnusedImports"/>
<!-- 检查是否导入了多余的包 -->
<module name="RedundantImport"/>
<!-- 修饰符检查 -->
<!-- 检查修饰符的顺序是否遵照 java 语言规范,默认 public、protected、private、abstract、static、final、transient、volatile、synchronized、native、strictfp -->
<module name="ModifierOrder"/>
<!-- 检查接口和 annotation 中是否有多余修饰符,如接口方法不必使用 public -->
<module name="RedundantModifier"/>
<!-- 是否有嵌套代码块 -->
<module name="AvoidNestedBlocks"/>
<!-- 是否有空代码块 -->
<module name="EmptyBlock"/>
<!-- 代码块是否缺失 {} -->
<module name="NeedBraces"/>
<!-- 左大括号位置 -->
<module name="LeftCurly"/>
<!-- 右大括号位置 -->
<module name="RightCurly"/>
<!-- 检查数组类型定义的样式 -->
<module name="ArrayTypeStyle" />
<!-- 检查 switch 语句是否具有“default”子句 -->
<module name="MissingSwitchDefault" />
<!--检查switch中case后是否加入了跳出语句,例如:return、break、throw、continue -->
<module name="FallThrough" />
<!-- 检查 long 型定义是否有大写的“L” -->
<module name="UpperEll" />
<module name="EmptyForInitializerPad"/>
<module name="EmptyForIteratorPad"/>
<module name="EmptyLineSeparator">
<property name="allowNoEmptyLineBetweenFields" value="true" />
</module>
<module name="GenericWhitespace"/>
<module name="MethodParamPad"/>
<module name="NoLineWrap"/>
<module name="OperatorWrap"/>
<module name="ParenPad"/>
<module name="SingleSpaceSeparator"/>
<module name="TypecastParenPad"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround"/>
</module>
</module>
将配置文件保存到项目的某个路径下,比如:style/checkstyle.xml
3.2 添加 maven 插件
<build>
<plugins>
<plugin>
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-checkstyle-plugin -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>x.y.z</version>
<configuration>
<!-- 指定了代码规范检查的规则文件的相对路径 -->
<configLocation>style/checkStyle.xml</configLocation>
<includeTestSourceDirectory>false</includeTestSourceDirectory>
<encoding>${project.build.sourceEncoding}</encoding>
<!-- 检测结果是否在控制台输出 -->
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
</configuration>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>