4
我有这样的代码时,如Java 7(Eclipse的编译器)编译它编译罚款,但是当我设置的项目设置为Java 8失败:通配符泛型在Java 7中的表现不同,8
package scratch;
class Param<T extends Comparable<T>> {
public Comparable<?> get() {
return null;
}
}
public class Condition<T extends Comparable<T>> {
public static <T extends Comparable<T>> Condition<T> isInRange(T lower, T upper) {
return null;
}
public void foo() {
Comparable bound = null; // Line 15
Param<?> param = new Param<Double>();
Condition.isInRange(param.get(), bound); // Line 17
}
}
在Java 7,我收到以下警告:
- 第15行:Comparable是原始类型。引用泛型类型可比应该是参数
- 17行:类型安全:类型条件的一般方法isInRange(T,T)的未选中调用isInRange(可比,可比)
当我行添加<?>
15,报警消失了,后来我在第17行出现错误:
绑定不匹配: 类型条件的一般方法isInRange(T,T)是不适用的参数 (可比,可比)。推断 类型可比不是一个有效的替代品 界参数>
有谁知道究竟是什么原因导致这种incompability?
PS:我添加了这些丑陋蒙上使代码的Java的两个版本下进行编译:
Condition.isInRange((Comparable)param.get(), (Comparable) bound);
eclipse编译器在泛型方面有一些缺陷,所以你应该用'javac'进行测试。 – Kayaman
这与通配符无关,但与“绑定”变量的* raw类型*无关。在Java-7中,这有效地关闭了所有关于“isInRange”方法调用的检查。在Java-8中,目标类型仍然检测到嵌套调用的无效,类似于[此场景](http://stackoverflow.com/a/26285613/2711488)。我不明白,为什么你认为你的类型转换为原始的“比较器”比原始类型的初始使用更丑陋。当然,第二种类型转换是无意义的,因为“绑定”已经是一个原始的“可比较”了。 – Holger
@Kayaman:在这种情况下,Eclipse完全符合'javac'。 – Holger