Как правило, исходный код Java был передовым. До Java 8, насколько мне известно, и скомпилированные классы, и исходные файлы были совместимы с более поздними версиями JDK/JVM. [Обновление: это неверно, см. Комментарии re 'enum' и т.д. Ниже.] Однако с добавлением методов по умолчанию в Java 8 это больше не имеет места.
Например, библиотека, которую я использовал, имеет реализацию java.util.List
, которая включает List<V> sort()
. Этот метод возвращает копию содержимого отсортированного списка. Эта библиотека, развернутая как зависимость файла jar, отлично работала в проекте, построенном с использованием JDK 1.8.
Однако позже мне пришлось перекомпилировать библиотеку, используя JDK 1.8 и
Я обнаружил, что библиотека больше не компилируется: класс List
-implementing со своим собственным методом sort()
теперь конфликтует с методом Java 8 java.util.List.sort()
по умолчанию. Метод Java 8 sort()
по умолчанию сортирует список на месте (возвращает void
); мой метод библиотеки sort()
- поскольку он возвращает новый отсортированный список - имеет несовместимую подпись.
Итак, мой основной вопрос:
- Разве JDK 1.8 не вводит форвардную несовместимость для исходного кода Java из-за методов по умолчанию?
также:
- Является ли это первым таким форвардным несовместимым изменением?
- Было ли это рассмотрено или обсуждено, когда методы по умолчанию разработаны и реализованы? Документировано ли оно где-нибудь?
- Было ли (по общему признанию, небольшое) неудобство скидкой и преимуществами?
Ниже приведен пример некоторого кода, который компилируется и запускается под версиями 1.7 и работает под 1,8 - но не компилируется под 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;
}
}
}
Ниже показано, как этот код компилируется (или не выполняется) и выполняется.
> 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