Java:循环泛型类型关系不允许从超类型转换(javac bug)

iva*_*off 5 java generics types casting

我遇到了Java编译器的一个完全奇怪的行为.
当涉及循环泛型类型关系时,我无法将超类型强制转换为子类型.

JUnit测试用例重现问题:

public class _SupertypeGenericTest {

    interface ISpace<S extends ISpace<S, A>, A extends IAtom<S, A>> {
    }

    interface IAtom<S extends ISpace<S, A>, A extends IAtom<S, A>> {
    }

    static class Space
            implements ISpace<Space, Atom> {
    }

    static class Atom
            implements IAtom<Space, Atom> {
    }

    public void test() {
        ISpace<?, ?> spaceSupertype = new Space();
        IAtom<?, ?> atomSupertype = new Atom();

        Space space = (Space) spaceSupertype;  // cast error
        Atom atom = (Atom) atomSupertype;  // cast error
    }
}
Run Code Online (Sandbox Code Playgroud)

编译错误输出:

_SupertypeGenericTest.java:33: inconvertible types
found   : pinetag.data._SupertypeGenericTest.ISpace<capture#341 of ?,capture#820 of ?>
required: pinetag.data._SupertypeGenericTest.Space
                Space space = (Space) spaceSupertype;
                                    ^

_SupertypeGenericTest.java:34: inconvertible types
found   : pinetag.data._SupertypeGenericTest.IAtom<capture#94 of ?,capture#48 of ?>
required: pinetag.data._SupertypeGenericTest.Atom
                Atom atom = (Atom) atomSupertype;
                                ^
2 errors
Run Code Online (Sandbox Code Playgroud)

注意:我正在使用Netbeans最新的trunk,捆绑的Ant,最新的Java 6版本.
我尝试从命令行使用Ant(Netbeans生成build.xml文件),但它会导致相同的错误.

怎么了?
是否有一种优雅的方式来解决问题?

奇怪的是:Netbeans没有在给定代码中标记错误(甚至不是警告).

编辑:
不,现在我什么都不懂!
Eclipse 3.4.1既不标记警告也不标记错误,并且编译代码没有问题!
怎么会这样?我想,使用命令行中的Ant和Netbeans提供的build.xml将是中立的.
我错过了什么吗?

编辑2:
使用JDK7库和JDK7代码格式,netbeans编译没有错误/警告!
(我使用的是1.7.0-ea-b55)

编辑3:
更改标题以表明我们正在处理javac错误.

Joa*_*uer 2

我并不声称很容易理解那些复杂的泛型类型,但是如果您发现一些代码可以在(Eclipse 编译器)javac中编译,但不能在ecj(Eclipse 编译器)中编译,那么请向SunEclipse提交一份错误报告,并清楚地描述情况(最好如果您还提到您提交了两个错误报告并提及了它们各自的 URL(尽管对于 Sun 来说,可能需要一段时间才能公开访问该错误)。

我过去曾这样做过,并得到了很好的回应

  1. 其中一个团队找出了正确的方法是什么(给出编译错误、警告或什么也不给出)
  2. 并且修复了有问题的编译器

由于两个编译器都实现相同的规范,因此如果只有其中一个编译器编译代码,那么根据定义,其中一个编译器就是错误的。

作为记录:

我尝试使用javac(javac 1.6.0_13)和ecj(Eclipse Java Compiler 0.894_R34x,3.4.2版本)编译示例代码,并javac大声抱怨并未能生成任何.class文件,而ecj只抱怨一些未使用的变量(警告)并生成了所有预期的.class文件。