尽管使用 Java 8 个功能,项目如何支持 Java 7 个
How can a project support Java 7 despite using Java 8 features
我正在审查 github 上的 HikariCP 项目,它在其源代码中声明支持 "Java 7 and Java 8 maven artifact",它使用了一些 Java 8 个功能:
java.util.function.Consumer;
java.util.function.Predicate;
java.util.function.UnaryOperator;
我猜如果这个项目被其他人引用Java7,就会出错。那么,该项目是如何同时支持 Java 7 和 Java 8 的呢?
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<extensions>true</extensions>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
可能是项目的错误
指定源和目标级别仅尊重语言特性并影响字节码版本。未检查 API。
如果他们使用 JDK 8 构建项目,则项目构建良好。但我怀疑它会用 JDK 7.
编译
他们可能认为在这里指定 1.7 将使其支持 Java SE 7,这不会自动正确。
您是否尝试过使用 Java SE 7 访问图书馆?
该项目的好消息是,似乎很容易支持 Java SE 7。
FastList 只是一个 List 实现。由于 List 接口已在 Java SE 8 中得到扩展,因此即使它们仅抛出 UnsupportedOperationException,它们也被迫实现新方法。
通过使用 JDK 7 构建项目,他们可以轻松删除那些看似不需要的方法。
这不是一个错误(正如我自己所想的)。该项目确实使用了 Java 8 中的 classes。它不使用 Java 7 进行编译,并且其 Maven 构建也不使用 运行 和 Java 7 .
但是,由于 Java 8 特定功能(如 Lambda)在源代码中没有任何地方使用,因此 运行 和 Java 7.
尝试创建一个 Java 7 项目,将 HikariCP 声明为依赖项,然后 运行 执行以下代码:
import com.zaxxer.hikari.util.FastList;
public class Main {
public static void main(String[] args) {
FastList<String> fastList = new FastList<>(String.class);
fastList.add("Hello");
System.out.println(fastList);
}
}
它 运行 成功了。另一方面,以下代码失败:
fastList.removeIf(null);
这是因为 removeIf()
和其他一些方法使用 Java 8 中的 classes,因此不能 运行 和 Java 7。但是他们都扔UnsupportedOperationException
反正!您可能会注意到,唯一要导入 Java 8 classes 的 class 是 com.zaxxer.hikari.util.FastList
。我不确定他们为什么这样做。
UPDATE:只是想澄清项目字节码的版本是 1.7,可以使用反编译器或 hexdump 轻松验证。它的源代码确实符合 Java 7,因此可以用
构建
<source>1.7</source>
<target>1.7</target>
正如@Puce 指出的那样。
另一方面,必须用JDK 1.8编译,这样源代码中引用的Java 8 class在编译时是可用的。一旦代码被编译,它可以 运行 和 Java 7 只要不尝试加载丢失的 Java 8 class(来自 java.util.function
包在这种情况下)。
我正在审查 github 上的 HikariCP 项目,它在其源代码中声明支持 "Java 7 and Java 8 maven artifact",它使用了一些 Java 8 个功能:
java.util.function.Consumer;
java.util.function.Predicate;
java.util.function.UnaryOperator;
我猜如果这个项目被其他人引用Java7,就会出错。那么,该项目是如何同时支持 Java 7 和 Java 8 的呢?
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<extensions>true</extensions>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
可能是项目的错误
指定源和目标级别仅尊重语言特性并影响字节码版本。未检查 API。
如果他们使用 JDK 8 构建项目,则项目构建良好。但我怀疑它会用 JDK 7.
编译他们可能认为在这里指定 1.7 将使其支持 Java SE 7,这不会自动正确。
您是否尝试过使用 Java SE 7 访问图书馆?
该项目的好消息是,似乎很容易支持 Java SE 7。 FastList 只是一个 List 实现。由于 List 接口已在 Java SE 8 中得到扩展,因此即使它们仅抛出 UnsupportedOperationException,它们也被迫实现新方法。
通过使用 JDK 7 构建项目,他们可以轻松删除那些看似不需要的方法。
这不是一个错误(正如我自己所想的)。该项目确实使用了 Java 8 中的 classes。它不使用 Java 7 进行编译,并且其 Maven 构建也不使用 运行 和 Java 7 .
但是,由于 Java 8 特定功能(如 Lambda)在源代码中没有任何地方使用,因此 运行 和 Java 7.
尝试创建一个 Java 7 项目,将 HikariCP 声明为依赖项,然后 运行 执行以下代码:
import com.zaxxer.hikari.util.FastList;
public class Main {
public static void main(String[] args) {
FastList<String> fastList = new FastList<>(String.class);
fastList.add("Hello");
System.out.println(fastList);
}
}
它 运行 成功了。另一方面,以下代码失败:
fastList.removeIf(null);
这是因为 removeIf()
和其他一些方法使用 Java 8 中的 classes,因此不能 运行 和 Java 7。但是他们都扔UnsupportedOperationException
反正!您可能会注意到,唯一要导入 Java 8 classes 的 class 是 com.zaxxer.hikari.util.FastList
。我不确定他们为什么这样做。
UPDATE:只是想澄清项目字节码的版本是 1.7,可以使用反编译器或 hexdump 轻松验证。它的源代码确实符合 Java 7,因此可以用
构建<source>1.7</source>
<target>1.7</target>
正如@Puce 指出的那样。
另一方面,必须用JDK 1.8编译,这样源代码中引用的Java 8 class在编译时是可用的。一旦代码被编译,它可以 运行 和 Java 7 只要不尝试加载丢失的 Java 8 class(来自 java.util.function
包在这种情况下)。