转换为泛型类的通用子类型

时间:2013-07-26 14:06:56

标签: java generics casting subclass

假设我有这个:

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!
}

为什么?有什么明显的东西我在这里不见了吗?

1 个答案:

答案 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, ?>分别为ST,前两个条件显然不成立。

留下第三个条件 - 如果我们能够识别除Base<T>以外的Derived<T, ?>的子类型,其类型参数不包含在Derived<T, ?>的类型参数中,则不会成立。如果警告正确,则必须存在这样的子类型,但我无法识别。例如,Derived<?, ?>不起作用,因为它不是Base<T>的子类型。