The following code
class GenericCompilationFailureDemo {
List extends GenericCompilationFailureDemo> newList() {
return new ArrayList
This is apparently a javac7 bug. It should be allowed per casting conversion rules [1]
One of the rules allows a narrowing reference conversion ... followed by an unchecked conversion
Casting List => List
is allowed by this rule
List => List // narrowing reference conversion
List => List // unchecked conversion
That's not all the story though; the spec has further rules to forbid casting like List
, for they are provably distinct parameterized
types. There is no object belonging to the two types at the same time, so compiler think it's better to disallow this apparent programming error. (You can bypass it by explicitly List
)
The last rule doesn't apply here though; so it looks like a javac7 bug.
Why the last rule doesn't apply: so we are casting List extends A>
to List
. Here capture conversion is applied to List extends A>
[2] so we are actually casting List
to List
, where T
is a new type variable with upper bound A
.
The question is whether List
and List
are provably distinct parameterized types. My understanding is that it's false (it has to be false for your first two examples to compile). Since T
is a type variable, it can take a value to make List
and List
the same parameterized type (i.e. when T=A
). This reasoning should work for any type A
.
[1] http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.5
[2] http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#341306