尽管使用Java 8功能,项目如何支持Java 7

law*_*nce 5 java maven java-7 java-8

我正在审查github上的HikariCP项目,它声明它支持"Java 7和Java 8 maven artifact",在其源代码中,它使用了一些Java 8特性:

java.util.function.Consumer;
java.util.function.Predicate;
java.util.function.UnaryOperator;
Run Code Online (Sandbox Code Playgroud)

我想如果其他人使用Java 7引用此项目,则会发生错误.那么,该项目如何使其同时支持Java 7和Java 8?

vem*_*mpo 5

这不是一个错误(正如我自己想的那样).该项目确实使用来自Java 8的类.它不使用Java 7进行编译,并且其Maven构建也不能与Java 7一起运行.

但是,由于Lambda中特定于Java 8的特性在源代码中没有使用,因此它确实与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);
    }
}
Run Code Online (Sandbox Code Playgroud)

它运行成功.另一方面,以下代码失败:

fastList.removeIf(null);
Run Code Online (Sandbox Code Playgroud)

这是因为removeIf()一些其他的方法使用类从Java 8,因此不能与Java 7上运行,但它们都扔UnsupportedOperationException !您可能会注意到导入Java 8类的唯一类是com.zaxxer.hikari.util.FastList.我不确定他们为什么这样做.

更新:只是想澄清项目字节码的版本是1.7,因为可以使用反编译器或hexdump轻松验证.它的源代码符合Java 7,因此可以构建

<source>1.7</source>
<target>1.7</target>
Run Code Online (Sandbox Code Playgroud)

正如@Puce指出的那样.

另一方面,它必须使用JDK 1.8进行编译,以便在编译期间源代码中引用的Java 8类可用.编译代码后,只要没有尝试加载缺少的Java 8类(java.util.function在这种情况下来自包),它就可以与Java 7一起运行.

  • @vempo:具有兼容的字节代码并不一定意味着符合标准的工作应用程序.如上所述,允许JVM实现急切地解析(甚至间接)引用的类,这意味着您的代码可能在兼容的JVM上失败,即使它恰好适用于Oracle的特定实现.当然,如果将`java.util.function.*`类添加到bootstrap类路径中,它将适用于所有JVM,但这也是标准之外的操作. (2认同)
  • @vempo:我想,从上下文中可以明显看出我们只讨论你的Java 7兼容字节码.您的项目编译为Java 7字节代码,允许它使用**Oracle的**JDK 1.7运行,仅此而已.它仍然不是一个(完全)兼容的Java 7应用程序,因为它间接引用Java 7中不存在的类.如果你可以使用它,因为它在Oracle的JVM和大多数其他主流JVM上运行,它没关系,但你应该知道... (2认同)