目前为止,Java源代码通常是向前兼容的。 我所知道的是,在Java 8之前,编译后的类和源文件都可以与后来的JDK / JVM版本向前兼容。 [更新:这是不正确的,请参见下面有关“枚举”等的评论。] 然而,随着在Java 8中添加默认方法,这似乎不再是这种情况。
例如,我一直在使用的库包含一个java.util.List
实现,其中包括一个List<V> sort()
,该方法返回已排序列表的内容副本。将此库部署为jar文件依赖项后,在使用JDK 1.8构建的项目中运行良好。
但是,稍后我有机会使用JDK 1.8重新编译库本身,我发现该库不再编译:具有自己的sort()
方法的List
实现类现在与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