代码之家  ›  专栏  ›  技术社区  ›  Andremoniy

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

  •  5
  • Andremoniy  · 技术社区  · 9 年前

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

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

    这是相当合理的实施。现在我们尝试用Java 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
    

    在此,我想提出两个问题:

    1. 即使有 javac -source 1.7 -target 1.7 使用JDK 8的选项我收到 相同的 错误-为什么?我认为这些选项应该允许编译遗留代码。

    2. 一般来说向后兼容性如何?

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

    bash-3.2$ javac -version
    javac 1.8.0_65
    bash-3.2$ javac -source 1.7 -target 1.7 MyArrayList.java 
    warning: [options] bootstrap class path not set in conjunction with -source 1.7
    MyArrayList.java:7: 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 MyArrayList
        E#2 extends Object declared in class ArrayList
    1 error
    1 warning
    
    2 回复  |  直到 9 年前
        1
  •  8
  •   JB Nizet    9 年前
    1. 因为即使有了这些选项,您仍然在针对Java8类进行编译。JDK不知道哪些方法出现在JDK的哪个版本中。所有这些选项都告诉编译器在编译的代码中只接受Java7语法,并生成Java7字节码。您必须实际传递到JDK7类的链接(使用 -bootclasspath 选项)交叉编译。

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

        2
  •  7
  •   Community CDub    7 年前
    1. -source 1.7 只表示源代码使用Java 7语言特性。 -target 1.7 表示输出的字节码针对JVM的特定版本。然而 您仍在针对JDK 8进行编译 。由于您是交叉编译,您必须告诉 javac 其中Java 7的引导和扩展类使用 -bootclasspath -extdirs
    2. Default methods 在接口(Java8中引入的)中,您可以在不破坏现有代码的情况下添加新功能。这不是一个防弹的解决方案,可能会有一些小问题( this answer 更详细地解释了问题)。但总体而言,向后兼容性问题相当罕见。