简体   繁体   English

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

[英]Casting to generic subtypes of a generic class

Suppose I have this: 假设我有这个:

class Base<T> {}

class Derived<T> extends Base<T> {}

Then in my code, I can safely cast without a warning like this: 然后在我的代码中,我可以安全地进行铸造,而不会发出如下警告:

public <T> void foo(Base<T> base) {
    Derived<T> f = (Derived<T>) base; // fine, no warning
}

which is fine. 很好 But if the derived class has more type parameters, it doesn't work any more: 但是,如果派生类具有更多类型参数,它将不再起作用:

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

Why is that? 这是为什么? Is there something obvious I'm missing here? 有什么明显的我想念的地方吗?

This seems like a bug to me. 对我来说,这似乎是一个错误。 From JLS §5.5.2. JLS§5.5.2。 Checked Casts and Unchecked Casts : 已检查的演员表和未检查的演员表

A cast from a type S to a parameterized type (§4.5) T is unchecked unless at least one of the following conditions holds: 除非至少满足以下条件之一,否则不检查从类型S到参数化类型(第4.5节)T的强制转换:

  • S <: T S <:T

  • All of the type arguments (§4.5.1) of T are unbounded wildcards T的所有类型参数(第4.5.1节)都是无界通配符

  • T <: S and S has no subtype X other than T where the type arguments of X are not contained in the type arguments of T. T <:S和S除了T的类型参数中不包含X的类型参数以外,没有T的子类型X。

Given your types Base<T> and Derived<T, ?> as S and T respectively, the first two conditions clearly don't hold. 给定类型Base<T>Derived<T, ?>分别为ST ,前两个条件显然不成立。

That leaves the third condition - which won't hold if we can identify a subtype of Base<T> other than Derived<T, ?> whose type arguments are not contained in the type arguments of Derived<T, ?> . 这使得第三个条件-这将不成立,如果我们能够确定的亚型Base<T>Derived<T, ?>其类型参数不包含在该类型参数Derived<T, ?> If the warning is correct, such a subtype must exist, but I can't identify one. 如果警告是正确的,则必须存在这样的子类型,但我无法确定一个。 For example, Derived<?, ?> doesn't work because it isn't a subtype of Base<T> . 例如, Derived<?, ?>不起作用,因为它不是Base<T>的子类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM