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错误.
我并不声称很容易理解那些复杂的泛型类型,但是如果您发现一些代码可以在(Eclipse 编译器)javac中编译,但不能在ecj(Eclipse 编译器)中编译,那么请向Sun和Eclipse提交一份错误报告,并清楚地描述情况(最好如果您还提到您提交了两个错误报告并提及了它们各自的 URL(尽管对于 Sun 来说,可能需要一段时间才能公开访问该错误)。
我过去曾这样做过,并得到了很好的回应
由于两个编译器都实现相同的规范,因此如果只有其中一个编译器编译代码,那么根据定义,其中一个编译器就是错误的。
作为记录:
我尝试使用javac(javac 1.6.0_13)和ecj(Eclipse Java Compiler 0.894_R34x,3.4.2版本)编译示例代码,并javac大声抱怨并未能生成任何.class文件,而ecj只抱怨一些未使用的变量(警告)并生成了所有预期的.class文件。