【发布时间】:2016-01-12 22:39:39
【问题描述】:
简单的问题。在 Java 8 中,我们在 JDK 类中有大量新方法。假设我们使用 Java 7(或 Java 6)创建了这样的类:
class MyArrayList<E> extends ArrayList<E> {
public void sort(Comparator<E> c) {
// some sort
}
}
这是相当合理的实现。现在我们尝试用 Java 8 编译它并收到预期的编译错误:
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
在这里我想提出两个问题:
即使使用 JDK 8 使用
javac -source 1.7 -target 1.7选项,我也会收到 same 错误 - 为什么?我认为这些选项应该允许编译遗留代码。一般来说向后兼容性如何?
编辑确切地说,可能是我做错了什么? 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
【问题讨论】:
-
这在 javac 文档中有描述。 “但 javac 也支持交叉编译,其中类是针对不同 Java 平台实现的引导和扩展类编译的。交叉编译时使用 -bootclasspath 和 -extdirs 选项很重要。”
-
-source 1.7确保不使用 Java 8 的语言特性,-target 1.7确保生成的字节码与 1.7 JVM 兼容。两者都不会更改正在使用的运行时库。您需要更多选项来在编译期间将运行时库更改为 Java 7。 -
@Tunaki 非常感谢。这是我第二个问题的答案。
-
源和目标指定要使用的语言版本,而不是要使用的库版本。
标签: java java-8 backwards-compatibility