假设我有这个:
class Base<T> {}
class Derived<T> extends Base<T> {}
然后在我的代码中,我可以安全地投射而没有这样的警告:
public <T> void foo(Base<T> base) {
Derived<T> f = (Derived<T>) base; // fine, no warning
}
哪个好。但是如果派生类有更多的类型参数,它就不再起作用了:
class Base<T> {}
class Derived<T, U> extends Base<T> {}
public <T> void foo(Base<T> base) {
Derived<T, ?> f = (Derived<T, ?>) base; // unchecked warning!
}
为什么?有什么明显的东西我在这里不见了吗?
答案 0 :(得分:5)
这对我来说似乎是个错误。来自JLS §5.5.2. Checked Casts and Unchecked Casts:
取消选中从S类型到参数化类型(§4.5)T的强制转换 除非至少满足下列条件之一:
S&lt;:T
T的所有类型参数(第4.5.1节)都是无界通配符
T&lt;:S和S除了T之外没有其他类型参数的子类型X. X不包含在T的类型参数中。
鉴于您的类型Base<T>
和Derived<T, ?>
分别为S
和T
,前两个条件显然不成立。
留下第三个条件 - 如果我们能够识别除Base<T>
以外的Derived<T, ?>
的子类型,其类型参数不包含在Derived<T, ?>
的类型参数中,则不会成立。如果警告正确,则必须存在这样的子类型,但我无法识别。例如,Derived<?, ?>
不起作用,因为它不是Base<T>
的子类型。