As a rule, Java source code was advanced. Prior to Java 8, as far as I know, both compiled classes and source files were compatible with later versions of JDK / JVM. [Update: this is incorrect, see comments re 'enum', etc. Below.] However, with the addition of default methods in Java 8, this no longer holds.
For example, the library I used has an implementation of java.util.List that includes List<V> sort() . This method returns a copy of the contents of the sorted list. This library, deployed as a jar file dependency, worked fine in a project built using JDK 1.8.
However, later I had to recompile the library using JDK 1.8 and I found that the library no longer compiles: the List -implementing class with its own sort() method now conflicts with the default Java 8 method java.util.List.sort() . The Java 8 method sort() by default sorts the list in place (returns void ); my library's sort() method - since it returns a new sorted list - has an incompatible signature.
So my main question is:
- Doesn't JDK 1.8 introduce forward incompatibility for Java source code due to default methods?
also:
- Is this the first such forward incompatible change?
- Was this considered or discussed when the default methods are designed and implemented? Is it documented somewhere?
- Was the (admittedly slight) inconvenience of discount and benefits?
Below is an example of some code that compiles and runs under versions 1.7 and works under 1.8 - but does not compile under 1.8:
import java.util.*; public final class Sort8 { public static void main(String[] args) { SortableList<String> l = new SortableList<String>(Arrays.asList(args)); System.out.println("unsorted: "+l); SortableList<String> s = l.sort(Collections.reverseOrder()); System.out.println("sorted : "+s); } public static class SortableList<V> extends ArrayList<V> { public SortableList() { super(); } public SortableList(Collection<? extends V> col) { super(col); } public SortableList<V> sort(Comparator<? super V> cmp) { SortableList<V> l = new SortableList<V>(); l.addAll(this); Collections.sort(l, cmp); return l; } } }
The following shows how this code is compiled (or not executed) and executed.
> c:\tools\jdk1.7.0_10\bin\javac Sort8.java > c:\tools\jdk1.7.0_10\bin\java Sort8 this is a test unsorted: [this, is, a, test] sorted : [this, test, is, a] > c:\tools\jdk1.8.0_05\bin\java Sort8 this is a test unsorted: [this, is, a, test] sorted : [this, test, is, a] > del Sort8*.class > c:\tools\jdk1.8.0_05\bin\javac Sort8.java Sort8.java:46: error: sort(Comparator<? super V>) in SortableList cannot implement sort(Comparator<? super E>) in List public SortableList<V> sort(Comparator<? super V> cmp) { ^ return type SortableList<V> is not compatible with void where V,E are type-variables: V extends Object declared in class SortableList E extends Object declared in interface List 1 error
java java-8 default-method forward-compatibility
Paul Jul 02 '15 at 15:05 2015-07-02 15:05
source share