Why does a generic cast of a List<? extends Set..> to List<Set..> succeed on Sun JDK 6 but fail to compile on Oracle JDK 7?

只谈情不闲聊 提交于 2019-12-03 05:45:48

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<A> => List<B> is allowed by this rule

List<A> => List   // narrowing reference conversion
List => List<B>   // unchecked conversion

That's not all the story though; the spec has further rules to forbid casting like List<String>=>List<Integer>, 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<String>=>List=>List<Integer>)

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<A>. Here capture conversion is applied to List<? extends A> [2] so we are actually casting List<T> to List<A>, where T is a new type variable with upper bound A.

The question is whether List<T> and List<A> 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<T> and List<A> 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!