Maven 设置 Java 版本

Last Modified: 2023/05/24

概述

当我们借助 mvn 构建项目的时候,需要指定的源码的版本和编译目标版本,指定的方式就是在 pom.xml 中加入一小段配置而已,但是配置方式多种多样,让许多同学都深感头痛,今天我们就总结下目前指定 java 版本的几种方式。

配置方式汇总

方式一

<properties>
    <java.version>1.8</java.version>
</properties>

这种方式是 spring boot 项目特有的,如果不是 spring boot 项目就不需要考虑这种方式了。通过上面的配置将 source 和 target 的版本都设置为 1.8。

方式二

<plugin>    
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
    </configuration>
</plugin>

这种方式就是最经典的配置方式了,不赘述。

方式三

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

这种方式等价于方式二,mvn 编译插件文档中 指出,如果方式二中没有指定 <source><target>,那么 maven 编译插件就使用 maven.compiler.sourcemaven.compiler.target 指定的 Java 版本,可见方式二的优先级更高。

方式四

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <release>9</release>
    </configuration>
</plugin>

从 java 9 开始我们可以使用这种方式来指定 java 版本。这种方式相当于将 source 和 target 都设置为 java 9。因为 source 和 target 大部分情况下都是相同的,因此可以认为这种写法更简洁。

方式五

<properties>
    <maven.compiler.release>9</maven.compiler.release>
</properties>

等价于方式四,同样地,方式四的优先级比该配置方式优先级更高。从结果来看,其实不管哪种方式都是等价的,都是为了指定 source 和 target 版本,只不过第一种方式特定于 spring boot,而方式四和五出来比较晚一点而已。

使用其他版本的 jdk 编译项目

有时候我们本地为了开发方便,装有多个 Java 版本,而 JAVA_HOME 指向的版本可能比较低,假如是 1.8,但是我们的 maven 项目使用了 java 15 的特性,此时即便我们在 pom.xml 中指定了正确的 source 和 target,仍然不能编译成功,因为一个低版本的 Jdk 无法编译高版本的语言特性,因此我们需要告诉 maven 使用更高版本 jdk 的编译器,下面的代码中我们通过 <executable> 标签配置使用了 jdk17 下面的编译器。

需要注意配置 <fork>true</fork>。默认情况下 maven 使用内置的编译器,通过 <fork>true</fork>,maven 会使用你指定的编译器,并在另外一个进程中运行 javac 编译代码。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>15</source>
        <target>15</target>
        <fork>true</fork>
        <!-- 指定其他编译器的路径 -->
        <executable>/home/saltyfish/.jdks/corretto-17.0.5/bin/javac</executable>
    </configuration>
</plugin>

关于 source 和 target

开发环境的 jdk 版本可能很高,例如 jdk17,但是生产环境上的 JAVA 版本可能比较低,比方说是 1.8。此时我们要确保我们的代码只使用 1.8 的语言特性,不能使用了java 17 的语言特性或者 java17 新增加的方法,由于线上是 1.8,因此 target 需要设置为 1.8。由于 source 也是 1.8 的,因此 source 也指定为 1.8。

可见本地开发使用的 jdk 版本使用比线上环境高是可以的,只需要设置好编译的目标版本,保证编译目标版本不高于线上 java 版本。另外 source 和 target 并不总需要一致,但需要保证 target 的版本始终大于等于 source 版本。如果 source 比 target 高,运行时会报错,因为低版本的 jvm 无法支持高版本才有的特性和方法。

有问题吗?点此反馈!

温馨提示:反馈需要登录