问题
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:
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.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:
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.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:
-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 telljavac
where the bootstrap and extension classes for Java 7 exist using-bootclasspath
and-extdirs
- 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