我有一段代码在 Oracle JDK 7 和 Eclipse JDT 7 之间编译不一致,但由于我不确定哪个编译器犯了错误,我想在提交任何错误报告之前我应该在这里征求意见。
这是我能想出的最简单的测试来证明不一致:
interface Foo<S extends Foo<S, T>, T> {
// should this compile?
public <X extends Foo<S, Y>, Y> Y method1();
// what about this?
public <X extends Foo<? extends S, Y>, Y> Y method2();
}
Oracle JDK 在方法 1 上给出错误,但在方法 2 上没有,而 Eclipse 对这两种方法都没有问题。我什至不确定这两种方法都应该编译...
如果这两种方法都不应该从一开始就编译,那么以下几点就没有实际意义,但我觉得如果我们添加以下代码,两个编译器都会出错:
interface Bar extends Foo<Bar, Integer> {
}
class Bug {
void bug() {
Bar bar = null;
Double bubble;
// these fail as expected...
bar.<Foo<Bar, Double>, Double> method1();
bar.<Foo<? extends Bar, Double>, Double> method2();
// ...but these don't even though the inferred parametrisations should be
// the same as above
Double bobble = bar.method1();
Double babble = bar.method2();
}
}
当我们为方法 1 和方法 2 提供显式参数时,我找不到任何会导致有效调用返回 Double 的参数(即,当使用 Double 参数化 Y 时,我找不到 X 的有效参数)。这是我所期望的行为,据我所知,这里的 Y 应该只能使用 Integer 进行参数化。
但是,当我们让编译器推断参数化时,Oracle JDK 和 Eclipse JDT 都允许将 Y 推断为 Double 的调用。如果您将鼠标悬停在 Eclipse 中的调用上,它甚至会显示参数化与我们手动失败的参数设置完全相同,那么为什么会有不同的行为呢?
(此时分配给新变量 bobble 和 babble 的原因是悬停文本显示不同的参数 - 出于某种原因将 Double 替换为 Object - 如果我们再次分配给 bubble。它仍然编译调用并分配给 Doubles ,所以我不知道这是为什么。)
所以,这可能是我提出的另一个相当模糊的问题,但这里的任何人都可以为我解释一下吗?
编辑:
Eclipse 的错误报告:https ://bugs.eclipse.org/bugs/show_bug.cgi?id=398011