如果一个类B
扩展类A
,无法施放 List<A>
至List<B>
(下面为 1)。这是有道理的,因为如果允许,那么人们可以读到 B
从列表中删除,即使它不包含任何内容。
但是,在下面的代码中,从 List<? extends A>
中转换 2至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();
}
}
最佳答案
一个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
不幸的是,第一个 Actor 阵容未经检查。但如您所见,在该位置进行强制转换仍然是一个有效的选择。
<小时/>但是一个List<A>
实际上永远不可能成为List<B>
(除非你滥用原始类型),因为 List<A>
不可从 List<B>
分配(即 List<B>
不会“扩展” List<A>
),因此您无法转换:
List<A> list = new ArrayList<B>(); // Only works with: (List<A>) (List) new ArrayList<B>();
关于java - 如果 B 扩展 A,则无法将 List<A> 转换为 List<B> (有道理),但是为什么可以转换 List<?将 A> 扩展到列表 <B>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49184280/