Issue about java 8 backward compatibility: new methods in JDK

扶醉桌前 提交于 2019-12-23 11:48:14

问题


Simple question. In Java 8 we have huge number of new methods in JDK classes. Say we have created such class, using Java 7 (or Java 6):

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

This is quite reasonable implementation. Now we try to compile it with Java 8 and receive expectable compile error:

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

Here I would like to arise 2 questions:

  1. Even with javac -source 1.7 -target 1.7 option using JDK 8 I receive same error - why? I thought these options should allow compile legacy code.

  2. How about backward compatibility in general?

EDIT To be precise, may be I'm doing something wrong? 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

回答1:


  1. because even with these options, you're still compiling against the Java 8 classes. The JDK doesn't have any idea which methods appeared in what version of the JDK. All these options do is tell the compiler to accept only Java 7 syntax in the code you're compiling, and to generate Java 7 bytecode. You would have to pass actually link to the JDK 7 classes (using the -bootclasspath option) to cross-compile.

  2. Yes, it's a problem. Not huge, and the benefit of having all thses new default methods is more important than the inconvenience of having some rare non-compiling code.




回答2:


  1. -source 1.7 only says that the source uses Java 7 language features. -target 1.7 says that the outputted bytecode targets a specific version of the JVM. However, you are still compiling against JDK 8. Since you are cross-compiling, you have to tell javac where the bootstrap and extension classes for Java 7 exist using -bootclasspath and -extdirs
  2. Default methods in interfaces (that were introduced in Java 8) lets you add new functionality without breaking existing code. It's not a bulletproof solution and there can be minor issues (this answer explains the issues in some detail). But on the whole backwards-compatibility issues are quite rare.


来源:https://stackoverflow.com/questions/34755121/issue-about-java-8-backward-compatibility-new-methods-in-jdk

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!