title: Do Java 8 default methods break source compatibility?
body: <p>It has generally been the case the Java source code has been forward compatible.  Until Java 8, as far as I know, both compiled classes <em>and</em> source have been forward compatible with later JDK/JVM releases.  [Update: this is not correct, see comments re 'enum', etc, below.]  However, with the addition of default methods in Java 8 this appears to no longer be the case.</p>
  
  <p>For example, a library I have been using has an implementation of <code>java.util.List</code> which includes a <code>List&lt;V&gt; sort()</code>.  This method returns a copy of the contents of the list sorted. This library, deployed as a jar file dependency, worked fine in a project being built using JDK 1.8.</p>
  
  <p>However, later I had occasion to recompile the library itself using JDK 1.8 and
  I found the library no longer compiles: the <code>List</code>-implementing class with its own <code>sort()</code> method now conflicts with the Java 8 <code>java.util.List.sort()</code> default method.  The Java 8 <code>sort()</code> default method sorts the list in place (returns <code>void</code>); my library's <code>sort()</code> method - since it returns a new sorted list - has an incompatible signature.</p>
  
  <p>So my basic question is:</p>
  
  <ul>
  <li>Doesn't JDK 1.8 introduce a forward incompatibility for Java source code due to default methods?</li>
  </ul>
  
  <p>Also:</p>
  
  <ul>
  <li>Is this the first such forward incompatible change?</li>
  <li>Was this considered or discussed when default methods where designed and implemented?  Is it documented anywhere?</li>
  <li>Was the (admittedly small) inconvenience discounted versus the benefits?</li>
  </ul>
  
  <p>The following is an example of some code that compiles and runs under 1.7 and
  runs under 1.8 - but does not compile under 1.8:</p>
  
  <pre><code>import java.util.*;
  
  public final class Sort8 {
  
      public static void main(String[] args) {
          SortableList&lt;String&gt; l = new SortableList&lt;String&gt;(Arrays.asList(args));
          System.out.println("unsorted: "+l);
          SortableList&lt;String&gt; s = l.sort(Collections.reverseOrder());
          System.out.println("sorted  : "+s);
      }
  
      public static class SortableList&lt;V&gt; extends ArrayList&lt;V&gt; {
  
          public SortableList() { super(); }
          public SortableList(Collection&lt;? extends V&gt; col) { super(col); }
  
          public SortableList&lt;V&gt; sort(Comparator&lt;? super V&gt; cmp) {
              SortableList&lt;V&gt; l = new SortableList&lt;V&gt;();
              l.addAll(this);
              Collections.sort(l, cmp);
              return l;
          }
  
      }
  
  }
  </code></pre>
  
  <p>The following shows this code being compiled (or failing to) and being run.</p>
  
  <pre><code>&gt; c:\tools\jdk1.7.0_10\bin\javac Sort8.java
  
  &gt; c:\tools\jdk1.7.0_10\bin\java Sort8 this is a test
  unsorted: [this, is, a, test]
  sorted  : [this, test, is, a]
  
  &gt; c:\tools\jdk1.8.0_05\bin\java Sort8 this is a test
  unsorted: [this, is, a, test]
  sorted  : [this, test, is, a]
  
  &gt; del Sort8*.class
  
  &gt; c:\tools\jdk1.8.0_05\bin\javac Sort8.java
  Sort8.java:46: error: sort(Comparator&lt;? super V&gt;) in SortableList cannot implement sort(Comparator&lt;? super E&gt;) in List
                  public SortableList&lt;V&gt; sort(Comparator&lt;? super V&gt; cmp) {
                                         ^
    return type SortableList&lt;V&gt; 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
  </code></pre>