5

首先,一些背景知识(如果不感兴趣,请略略略过)。我很生气和困惑!这应该是一个非常简单的用例,实际上我的代码已经用 Eclipse JDT 编译器编译得很好,所以直到现在我一直在配置 Maven 以确保这样做。尽管它不能与 Oracle JDK 和 OpenJDK 一起编译,但它一直困扰着我,因为我认为这实际上可能是我的代码有问题,所以我再次调查了它。

我认为这个错误可能是在 JDT 编译器中允许它编译,而不是 Oracle JDK 和 OpenJDK 不允许它,我也测试过这两者。有问题的原始代码要复杂得多,因此我更难看出问题出在哪里,事实上,我很惊讶地看到在仍未编译的情况下可以将其减少到何种程度。

Eclipse JDT 编译器或 Oracle JDK 和 OpenJDK 都有一个相当大的(恕我直言)错误。

TL;博士

这是有问题的代码的一个相当小的表示。(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 上任何东西的类型边界时,它编译得很好,即使额外的接口与错误无关。

谁能让我放心?任何人都知道为此存在的错误报告,或者以前有过相关经验并且可以告诉我问题是什么?如果我没有得到任何确凿的答案,我会提交一些错误报告。

编辑:

有几个人指出我在使用 <S extends C, C> 时遇到了前向引用错误。不知道为什么我没有收到这个错误,它甚至在 Eclipse 中用 JDT 编译...

无论如何,它仍然无法使用 OpenJDK 7 或 Oracle JDK 7 / 8 为我编译,因此我修改了问题以消除该问题。

编辑2:

快速检查确认这种前向引用现在在 Java 7 中是合法的。应该如此!

编辑3:

我已经在http://bugs.sun.com/上发布了错误报告。如果/当它们被接受时,我会在这里发布链接。

4

3 回答 3

2

这显然是您应该报告的 javac 错误。在开放的 jdk 邮件列表之一上询问您可能会有更好的运气。但是今天是感恩节,所以...

虽然这不是泛型的基本用法,但它相当复杂。

于 2012-11-21T21:29:14.400 回答
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 编译器中编译

于 2012-11-21T21:05:03.723 回答
0

没试过,但在

public class Bug<X extends Property<?, ?> & Anything> {

两者都没有限制?。需要类似的东西:

public class Bug<C, X extends Property<C, ? extends C> & Anything> {
于 2012-11-21T22:53:41.000 回答