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
Backward Compatibility Java versions are expected to be binary backwards-compatible. For example, JDK 8 can run code compiled by JDK 7 or JDK 6. It is common to see applications leverage this backwards compatibility by using components built by different Java version.
The JDK compiler is not backward compatible. So code cannot be compiled by java 1.5 to run on 1.4. 2 for example. Save this answer.
JDK 8, 11, and 17 are all reasonable choices both for compiling and running Scala code. Since the JVM is normally backwards compatible, it is usually safe to use a newer JVM for running your code than the one it was compiled on, especially if you are not using JVM features designated “experimental” or “unsafe”.
Java 11 is backwards compatible with Java 8. So you can swiftly change from Java 8 to 11.
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.
-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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With