可能的Java编译器错误! 程序不能与某些编译器一起编译
首先,一点背景(如果不感兴趣,可以跳过一点)。 我很生气,很困惑! 这应该是一个非常简单的用例,事实上我的代码已经用Eclipse JDT编译器编译得很好,所以直到现在我一直在配置Maven以确保这样做。 尽管它不能用Oracle JDK和OpenJDK编译,但是我一直在困扰我,因为我认为它可能实际上是我的代码的问题,所以我再次研究它。
我想也许这个bug是在JDT编译器中允许它编译的,而不是Oracle JDK和OpenJDK因为不允许它,我也用它来测试这两个。 有问题的原始代码要复杂得多,所以我很难看到问题出在哪里,事实上,我很惊讶地发现在不编译的情况下可以减少这个问题的程度。
Eclipse JDT编译器或Oracle JDK和OpenJDK都有一个非常重要的(imho)错误。
TL; DR
这是相关代码的相当小的表示。 (Anything的类型绑定可以被任何接口替换,编译器行为不会改变):
public class Bug<X extends Property & Anything> { } interface Property extends PropertyConst { @Override public S get(); } interface PropertyConst { 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
这毫无意义。 返回类型显然是相关的,因为引用的两个方法之一必然会覆盖另一个。 我非常有信心这应该有效,事实上,最后1%缺失的唯一原因是,基本上使用仿制药这一点并没有被发现,但我发现没有相关的错误报告它。 (不可否认,我并不是很努力,因为http://bugs.sun.com/只是最糟糕的。你甚至可以通过bug报告是否仍然打开来过滤关键字搜索结果吗?呃。)
对我来说最令人困惑的部分是,当你删除X上Anything的类型绑定时,它编译得很好,即使额外的接口与错误无关。
任何人都可以放下心来吗? 任何人都知道存在的错误报告,或者之前有过相关经验,可以告诉我问题是什么? 如果我没有得到任何确凿的答案,我会提交一些错误报告。
编辑:
有几个人指出我有的前向引用错误。 不知道为什么我没有得到这个错误,它甚至在Eclipse中用JDT编译…
无论如何,它仍然无法使用OpenJDK 7或Oracle JDK 7/8编译,因此我修改了问题以解决该问题。
编辑2:
快速检查确认这种前向引用现在在Java 7中是合法的。应该如此!
编辑3:
我在http://bugs.sun.com/上发布了错误报告。 如果/当他们被接受,我会在这里发布链接。
这显然是你应该报告的javac错误。 你可能有更好的运气询问其中一个开放的jdk邮件列表。 但这是感恩节所以……
这不是generics的基本用法,但它非常复杂。
我已将您的样本输入我的Eclipse Indigo(3.7.1)并立即抱怨Property
接口的声明。
非法前向引用类型参数C.
对于public S get();
返回类型与PropertyConst.get()不兼容
将Property
声明更改为此
interface Property extends PropertyConst { @Override public S get(); }
修复了这两个错误,并在JDT和Sun的1.6编译器中编译
没试过,但是
public class Bug & Anything> {
两者都没有限制?
的。 人们会需要这样的东西:
public class Bug & Anything> {