If a class B
extends class A
, one cannot cast List<A>
to List<B>
(cast 1 below). This makes sense, because if it were allowed, then one could read a B
from the list even if it contained none.
However, in the code below, cast 2 from List<? extends A>
to List<B>
causes a warning. 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>
.
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();
}
}
答案 0 :(得分:3)
List<? extends A>
可能是List<B>
,因此您可以投射:
List<? extends A> list = new ArrayList<B>(); // lose type information
List<B> result = (List<B>) list; // regain type information
与您的行为类似:
Object o = "Hello World!"; // lose type information
String s = (String) o; // regain type information
不幸的是,第一次演员阵容未经检查。但正如你所看到的那样,那个地方的演员阵容仍然是一个有效的选择。
但List<A>
实际上永远不会是List<B>
(除非您滥用原始类型),因为List<A>
无法从List<B>
分配(即List<B>
}没有&#39;延伸&#39; List<A>
)所以你不能施展:
List<A> list = new ArrayList<B>(); // Only works with: (List<A>) (List) new ArrayList<B>();