可能的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> { 
Interesting Posts