我有这段代码,当我将其编译为Java 7(Eclipse编译器)时,它可以正常编译,但是当我将项目设置为Java 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是原始类型。应该将对泛型类型Comparable的引用参数化
- 17行:类型安全性:调用通配符方法isInRange(T, T)时未经检查,其类型为Condition
<?>
后,警告消失了,但是我遇到了第17行的错误:
有人知道确切的原因是什么导致这种不兼容吗?边界不匹配:类型Condition的泛型方法isInRange(T, T)不适用于参数(Comparable, Comparable)。推断出的类型Comparable不是受限参数的有效替代
PS:我添加了这些丑陋的转换以使代码在Java的两个版本下都能编译成功。
Condition.isInRange((Comparable)param.get(), (Comparable) bound);
javac
进行测试。 - Kayamanbound
变量的原始类型有关。在Java 7中,这实际上关闭了所有关于isInRange
方法调用的检查。在Java 8中,目标类型仍会检测嵌套调用的无效性,类似于此场景。我不明白为什么您认为将类型转换为原始的Comparator
比最初使用原始类型更难看。当然,由于bound
已经是原始的Comparable
,所以第二个类型转换没有意义。 - Holgerjavac
完全一致。 - HolgerisInRange
无法接受Comparable<?>
,因为该类型与所需参数类型不兼容。您可以通过使用原始类型来抑制泛型类型检查,但正确的解决方案是在第一次获取Comparable<?>
时防止其出现。但我们无法从您的示例中推导出为什么会有这些不完整的类型... - Holger