【发布时间】:2017-06-23 23:22:57
【问题描述】:
以下代码
class GenericCompilationFailureDemo {
List<? extends GenericCompilationFailureDemo> newList() {
return new ArrayList<GenericCompilationFailureDemo>();
};
void useList() {
List<GenericCompilationFailureDemo> list =
(List<GenericCompilationFailureDemo>) newList();
}
List<? extends Set<GenericCompilationFailureDemo>> newListOfSpecificSets() {
return new ArrayList<Set<GenericCompilationFailureDemo>>();
};
void useListOfSpecificSets() {
List<Set<GenericCompilationFailureDemo>> listOfSpecificSets =
(List<Set<GenericCompilationFailureDemo>>) newListOfSpecificSets();
}
List<? extends Set<? extends GenericCompilationFailureDemo>> newListOfSets() {
return new ArrayList<Set<? extends GenericCompilationFailureDemo>>();
};
void useListOfSet() {
List<Set<? extends GenericCompilationFailureDemo>> listOfSets =
(List<Set<? extends GenericCompilationFailureDemo>>) newListOfSets();
}
}
在 Sun JDK 1.6.0_20(Windows Vista 上为 64 位,但我认为这没有什么区别)下编译,但在 Oracle JDK 1.7.0_01(相同平台)下会导致以下编译失败:
[ERROR] src\main\java\GenericCompilationFailureDemo.java:[56,78] error: inconvertible types
请注意,useList 和 useListOfSpecificSets 中的前 两个 "extends-to-specific-type" 强制转换在 1.7.0_01 下仍然成功,所以看起来它与“双泛型扩展”。
任何想法可能在 6 和 7 之间发生了变化,以及观察到的行为是根据规范还是错误?
针对 Sanjay 的评论进行了编辑:
@Sanjay:啊哈,有趣!这是java -version的输出:
java version "1.7.0_01"
Java(TM) SE Runtime Environment (build 1.7.0_01-b08)
Java HotSpot(TM) 64-Bit Server VM (build 21.1-b02, mixed mode)
这里是javac GenericCompilationFailureDemo.java 的结果(与上面相同的代码,用于 List、ArrayList 和 Set 的导入语句):
GenericCompilationFailureDemo.java:30: error: inconvertible types
(List<Set<? extends GenericCompilationFailureDemo>>) newListOfSets()
;
^
required: List<Set<? extends GenericCompilationFailureDemo>>
found: List<CAP#1>
where CAP#1 is a fresh type-variable:
CAP#1 extends Set<? extends GenericCompilationFailureDemo> from capture of ?
extends Set<? extends GenericCompilationFailureDemo>
Note: GenericCompilationFailureDemo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
【问题讨论】:
-
不管怎样,这段代码在我的 JDK 7 上编译。你能把
java -version命令的整个输出连同“build”字符串一起发布吗? -
请粘贴确切的编译错误 + sanjay 的建议。 我相信在某些情况下,泛型在 java 7 中应该更简单...也许你发现了一个极端情况,旧的、复杂的 JDK 6 语法破坏了新的编译器。
-
@Sanjay:啊哈,有趣!请参阅编辑后的问题以获取对您的 cmets 的回复
-
javac 似乎有一个坏习惯,即自发拒绝根据 JLS 合法的泛型转换,请参阅bug 6790039,尤其是 looooong 列表 Related Bugs i> 那里提到过(目前有 16 个)- 你的可能在这个列表中 :)