I encounter a totally strange behavior of the Java compiler.
I can't cast a supertype to a subtype when cyclic generic type
relation is involved.
JUnit test case to reproduce the problem:
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
}
}
Compiler error output:
_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
Note: I'm using Netbeans latest trunk, bundled Ant, latest Java 6 release.
I tried using Ant from command line (Netbeans generates a build.xml file)
but it results in same errors.
What is wrong?
Is there an elegant way solve the problem?
The strange thing is: Netbeans doesn't mark errors (not even warnings) in given code.
EDIT:
No, now I understand nothing!
Eclipse 3.4.1 doesn't mark neither warnings nor errors, and compiles
the code without trouble!!!
How can this be? I thought, using Ant from command line along with
build.xml provided by Netbeans' would be neutral.
Am I missing something?
EDIT 2:
Using JDK7 library and JDK7 code format, netbeans compiles without
errors/warnings!
(I'm using 1.7.0-ea-b55)
EDIT 3:
Changed title to indicate that we're dealing with a javac bug.
I don't claim to easily understand those complex generic types, but if you find some code that compiles in javac
and doesn't in ecj
(the eclipse compiler), then file a bug report with both Sun and Eclipse and describe the situations cleary (best if you also mention that you filed both bug reports and mention their respective URLs, although for Sun it may take a while before the bug is publicly accessible).
I've done that in the past and got really good responses where
Since both compilers implement the same spec, one of them is by definition wrong, if only one of them compiles the code.
For the record:
I tried to compile the sample code with javac
(javac 1.6.0_13) and ecj
(Eclipse Java Compiler 0.894_R34x, 3.4.2 release) and javac
complained loudly and failed to produce any .class
files, while ecj
only complained about some unused variables (warnings) and produced all the expected .class
files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With