[英]If B extends A, one cannot cast List<A> to List<B> (makes sense), but then why can one cast List<? extends A> to List<B>?
If a class B
extends class A
, one cannot cast List<A>
to List<B>
(cast 1 below). 如果类
B
扩展了类A
,则不能将List<A>
为List<B>
(下面的广播1)。 This makes sense, because if it were allowed, then one could read a B
from the list even if it contained none. 这是有道理的,因为如果允许,那么即使列表中不包含
B
,也可以从列表中读取B
However, in the code below, cast 2 from List<? extends A>
但是,在下面的代码中,从
List<? extends A>
强制转换2 List<? extends A>
List<? extends A>
to List<B>
causes a warning. List<? extends A>
到List<B>
会引起警告。 Shouldn't it generate an error for the same reason as before? 它是否应该由于与以前相同的原因而产生错误? In the code, the list only contains one object that is an
A
but not a B
, and yet it is in a list deemed List<B>
. 在代码中,列表仅包含一个对象,该对象是
A
但不包含B
,但它在被视为List<B>
。
package test;
import java.util.LinkedList;
import java.util.List;
public class TypeLowerBoundCasting {
static class A {}
static class B extends A {}
static void method1() {
List<A> listOfAs = new LinkedList<A>();
listOfAs.add(new A());
// List<B> listOfAsAsListOfBs = (List<B>) listOfAs ; // cast 1: compiler error
// B b = listOfAsAsListOfBs.get(0); // that would be bad
}
static void method2() {
LinkedList<A> listOfAs = new LinkedList<A>();
listOfAs.add(new A());
List<? extends A> listOfAExtensions = listOfAs;
List<B> listOfAsAsListOfBs = (List<B>) listOfAExtensions; // cast 2: warning, but compiles
B b = listOfAsAsListOfBs.get(0); // that IS bad; causes a run-time error.
}
public static void main(String[] args) {
method2();
}
}
A List<? extends A>
List<? extends A>
List<? extends A>
might be a List<B>
, so you can cast: List<? extends A>
可能是List<B>
,所以可以强制转换:
List<? extends A> list = new ArrayList<B>(); // lose type information
List<B> result = (List<B>) list; // regain type information
Similar to how you can do: 与您的操作类似:
Object o = "Hello World!"; // lose type information
String s = (String) o; // regain type information
Unfortunately, the first cast is unchecked. 不幸的是,第一次演员表是未经检查的。 But a cast in that place is still a valid option, as you can see.
但是,如您所见,在该位置进行强制转换仍然是有效的选择。
But a List<A>
can never actually be a List<B>
(unless you abuse raw types), because List<A>
is not assignable from a List<B>
(ie List<B>
does not 'extend' List<A>
) so you can't cast: 但是
List<A>
实际上不能永远是List<B>
(除非您滥用原始类型),因为不能从List<B>
分配List<A>
(即List<B>
不会“扩展” List<A>
),因此您不能进行以下转换:
List<A> list = new ArrayList<B>(); // Only works with: (List<A>) (List) new ArrayList<B>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.