关于java 8向后兼容性的问题:JDK中的新方法

时间:2016-01-12 22:39:40

标签: java java-8 backwards-compatibility

简单的问题。在Java 8中,我们在JDK类中有大量新方法。假设我们使用Java 7(或Java 6)创建了这样的类:

_this

这是非常合理的实施。现在我们尝试使用Java 8编译它并收到可预期的编译错误:

class MyArrayList<E> extends ArrayList<E> {
        public void sort(Comparator<E> c) {
            // some sort
        }
}

在这里,我想提出2个问题:

  1. 即使使用JDK 8 error: name clash: sort(Comparator<E#1>) in MyArrayList and sort(Comparator<? super E#2>) in ArrayList have the same erasure, yet neither overrides the other public void sort(Comparator<E> c) { ^ where E#1,E#2 are type-variables: E#1 extends Object declared in class I.MyArrayList E#2 extends Object declared in class ArrayList 选项,我也会收到相同的错误 - 为什么?我认为这些选项应该允许编译遗留代码。

  2. 一般情况下向后兼容性怎么样?

  3. 编辑准确地说,可能是我做错了什么? JDK 1.8.0_65,Mac OS X:

    javac -source 1.7 -target 1.7

2 个答案:

答案 0 :(得分:7)

  1. -source 1.7仅表示源使用Java 7语言功能。 -target 1.7表示输出的字节码针对特定版本的JVM。但是,您仍在编译JDK 8 。由于您是交叉编译的,因此必须使用javac-bootclasspath
  2. 告诉-extdirs Java 7的引导程序和扩展类所在的位置。 接口中的
  3. Default methods(在Java 8中引入)允许您在不破坏现有代码的情况下添加新功能。它不是一个防弹解决方案,可能存在小问题(this answer详细解释了这些问题)。但总的来说,兼容性问题非常罕见。

答案 1 :(得分:6)

  1. 因为即使使用这些选项,您仍然在编译Java 8类。 JDK并不知道在哪个版本的JDK中出现了哪些方法。所有这些选项都告诉编译器只接受您编译的代码中的Java 7语法,并生成Java 7字节码。您必须将实际链接传递给JDK 7类(使用-bootclasspath选项)进行交叉编译。

  2. 是的,这是一个问题。并不是很大,并且拥有所有这些新的默认方法的好处比使用一些罕见的非编译代码的不便更重要。