java无法将实现接口A的对象添加到集合<?扩展A>
为什么我不能将a对象添加到集合中?因为B类是A的延伸
import java.util.*;
public class TestGeneric
{
public static void main(String[] args)
{
Collection<? extends A> collection = new ArrayList<A>();
A a = new B();
collection.add(a);
}
private static class B implements A {
public int getValue() { return 0; }
}
}
interface A { int getValue(); }
# 1 楼答案
如果有
<? extends A>
,那么此时编译器不知道正在使用的A
的子类是什么。因此,除了null
之外,向集合中添加任何对象都是不安全的你不能向
List<? extends T>
添加任何对象,因为你不能保证它真正指向的是什么类型的列表,所以你不能保证该对象在该列表中是允许的。唯一的“保证”是你只能从中阅读,你会得到一个T
或subclass of T
List<? extends Number>
可以通过以下三种方式实现:List<? extends Number> list = new ArrayList<Number>();
//数字“扩展”数字List<? extends Number> list = new ArrayList<Integer>();
//整数扩展数字List<? extends Number> list = new ArrayList<Double>();
//Double扩展数字因此,如果它是
new ArrayList<Double>()
,并且您正在添加integer
,那么这是一个错误,所以编译器可以安全地将访问限制为只读取而不添加添加也是安全的,因为我们知道父类,因此我们可以将任何子类分配给父类引用,如下所示:
这是安全的
因此,在
List<? extends Number>
中,我们知道集合中的所有元素都在以某种方式扩展Number
,因此我们可以读取它,因为我们可以将子类的实例分配给父类引用# 2 楼答案
原因如下:
然而,由于编译器知道coll只有扩展A的元素,所以仍然可以按原样检索它们
# 3 楼答案
简短的解释:
<? extends A>
意思是:一些特定但未知的类型扩展了A
。可能是A
本身或其任何亚型。因此,不能在此集合中插入任何元素:编译器无法知道add(object)
方法的参数的合法类型