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