gpt4 book ai didi

java - 使用 Java 7 配置的 Maven 编译器插件,但仍编译 Java 8 代码

转载 作者:搜寻专家 更新时间:2023-11-01 01:40:55 24 4
gpt4 key购买 nike

在我的项目中,我们将为 maven-compiler-plugin 使用 Java 7,我们假设在 Maven 编译后,所有使用 Java 8 的代码都不会编译成功。

但是,在我的例子中,有一个使用 Arrays.stream(T[] array) 的文件可以从 Java 8 使用并且它仍然可以成功编译。下面是一些配置 Java 版本的 pom.xml 文件。请您看一下,并告诉我为什么我的文件仍然可以成功编译,尽管我将其配置为 Java 7?

对于 pom.xml,我跳过了依赖关系等,只列出了属性和构建。

<properties>
<java.version>1.7</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>

对于我在 Java 8 中使用方法的文件,该行是这样的:

buffer.append(Arrays.stream(arg).collect(Collectors.joining("/")));

我想要的是,由于我在 Maven 中将 Java 版本配置为 7,并且在编译后,使用 Java 8 的文件应该无法成功编译并显示类似“... are allowed only at source level 1.8 或以上”。

最佳答案

<source> <target> 编译器插件的标志,直接映射到 -source and -target Java 编译器的选项 javac (当它被使用时)是generally misunderstood .

source不指示 javac使用指定的 JDK 版本编译 Java 源文件。它指示javac检查接受的源代码的版本,这是非常不同的。 Java 的主要版本有时会更改源代码的语法。例如,在 Java 1.4 中,您不能编写包含泛型的源代码,如 List<String> ;这是无效的。但是对于 Java 5,您可以,这意味着 JDK 5 编译器现在接受了一种新的 Java 源代码。 JDK 1.4 编译器,面对 List<String> ,只能出错,因为它不知道,当 JDK 5 编译器完全接受它时。设置 -source 1.4选项会告诉 JDK 5 编译器将源代码解释为 JDK 1.4 源代码;因此,如果该代码确实包含泛型,它将失败,因为该源代码在该版本中无效。这也意味着,如果源代码不包含任何特定于 Java 5 的源代码,它可以用 -source 1.4 编译得很好。 .

在此处的示例中,您遇到了 javac JDK 8 的编译器被指示检查关于 Java 7 的源代码。实际上,行

buffer.append(Arrays.stream(arg).collect(Collectors.joining("/")));

不使用任何 Java 8 特定的源代码。当然,它使用 Java 8 特定的,但源代码本身完全可以被 JDK 7 编译器理解。

  • 没有 lambda 表达式。添加一个简单的 map(i -> i)在你的管道中,然后是javac会报错,告诉你:

    lambda expressions are not supported in -source 1.7

    它检测到源代码使用了 JDK 7 源代码功能集中不可用的特定功能。

  • 没有在接口(interface)上调用静态方法。将您的 Stream 管道替换为 Stream.of(arg)而不是 Arrays.stream(arg) .这一次,你会得到一个错误:

    static interface method invocations are not supported in -source 1.7

    Arrays不是接口(interface),因此调用静态方法 stream该类上是完全有效的 JDK 7 源代码。然而,Stream是一个接口(interface)(当然,您正在使用的 JDK 8 编译器知道它),并且在 Java 8 之前,接口(interface)不能包含静态方法。因此,它不是有效的 Java 7 源代码。

还有更多类似的,但重点不是在这里描述它们( type annotationsrepeated annotationsmethod referencesintersection types in cast ... 你可以看到所有这些 in javac source code for example )。总而言之,没有理由javac以该源代码和 -source 7 失败选项。

target完全是另一头野兽;这不是这里的问题,所以只要说它指示 javac 就足够了生成针对指定版本 VM 的字节码。它不能以任何方式确保生成的字节代码将实际与所述版本的 VM 一起运行。如果你想确保,-bootclasspath选项将被使用。


这里回到手头的任务,其实就是让这里的编译失败。使用 Maven,you have 2 solutions :

  • Fork编译器,并设置一个 executable指向 JDK 7 编译器。
  • 或者(首选),使用 toolchains 的机制,以确保每个 Maven 插件(知道工具链)在整个构建过程中都使用此 JDK(例如 Javadoc 插件,它使用 JDK 安装的 javadoc 工具)。

关于java - 使用 Java 7 配置的 Maven 编译器插件,但仍编译 Java 8 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40982037/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com