【发布时间】:2012-11-10 05:02:51
【问题描述】:
首先,介绍一些背景知识(如果不感兴趣,请略略略过)。我很生气和困惑!这应该是一个非常简单的用例,实际上我的代码已经用 Eclipse JDT 编译器编译得很好,所以直到现在我一直在配置 Maven 以确保这样做。 虽然它不能与 Oracle JDK 和 OpenJDK 一起编译,但它一直困扰着我,因为我认为这实际上可能是我的代码有问题,所以我再次调查了它。
我认为错误可能在于 JDT 编译器允许它编译,而不是 Oracle JDK 和 OpenJDK 不允许它,我也测试过这两者。有问题的原始代码要复杂得多,因此我更难看出问题出在哪里,事实上,我很惊讶地看到在仍未编译的情况下可以将问题减少到何种程度。
无论是 Eclipse JDT 编译器还是 Oracle JDK 和 OpenJDK 都有一个相当大的(恕我直言)错误。
TL;DR
这是有问题的代码的一个相当小的表示。 (Anything的类型绑定可以被任何接口替换,编译器行为不会改变):
public class Bug<X extends Property<?, ?> & Anything> {
}
interface Property<C, S extends C> extends PropertyConst<C> {
@Override
public S get();
}
interface PropertyConst<C> {
public C get();
}
interface Anything {
}
总而言之,我认为这应该可以编译,但 Oracle JDK 7 & 8 和 OpenJDK 7 不同意。它确实使用 Eclipse Juno 为我编译。
当使用这些编译器中的任何一个编译时,上面的代码会出现类似以下错误,但使用 JDT 编译器可以正常工作:
Bug.java:3: error: types PropertyConst<?> and Property<?,?> are incompatible; both define get(), but with unrelated return types
public class Bug<X extends Property<?, ?> & Anything> {
^
1 error
这毫无意义。返回类型显然是相关的,因为所引用的两种方法之一必然会被 覆盖 另一个。我几乎有 99% 的信心认为这应该有效,事实上,最后 1% 缺失的唯一原因是泛型的使用太基本以至于没有被发现,但我没有发现相关的错误报告给它。 (诚然,我并没有努力,因为http://bugs.sun.com/ 是最糟糕的。你甚至可以通过错误报告是否仍然打开来过滤关键字搜索结果吗?呃。)
对我来说最令人困惑的部分是,当您删除 X 上任何东西的类型边界时,它编译得很好,即使额外的接口与错误无关。
谁能让我放心?任何人都知道为此存在的错误报告,或者以前有过相关经验并且可以告诉我问题是什么?如果我没有得到任何确凿的答案,我会提交一些错误报告。
编辑:
有几个人指出我在使用 时遇到了前向引用错误。不知道为什么我没有收到这个错误,它甚至在 Eclipse 中用 JDT 编译...
无论如何,它仍然无法使用 OpenJDK 7 或 Oracle JDK 7 / 8 为我编译,所以我修改了问题以消除该问题。
编辑 2:
快速检查确认这种前向引用现在在 Java 7 中是合法的。应该是这样!
编辑 3:
我已经在http://bugs.sun.com/ 上发布了错误报告。如果/当它们被接受时,我会在这里发布链接。
【问题讨论】:
-
问题是?不等于?
-
您是在 java 6 还是 7 上运行测试的?
-
如果你删除
Anything接口你还有错误吗? -
您是否还注意到 eclipse 中的“非法前向引用”错误? (另见this question)反转属性的泛型声明的参数
-
好的,再次阅读问题。适用于 JDK 1.5.0_10(需要删除接口 @Override)、1.6.0_27。 1.7.0_07 和 1.7.0_09 失败。
标签: java generics openjdk eclipse-jdt compiler-bug