为什么以下不起作用?
Vector<? extends SomeClass> v = new Vector<SomeClass>();
SomeClass e = new SomeClass();
v.add(e);
我收到一个编译错误:
Vector 类型中的方法 add(capture#1-of ? extends SomeClass) 不适用于参数 (SomeClass)
具有从一个类型扩展的通用通配符的集合不允许您添加到该类型Collection
。
由于编译器不知道您要添加的确切类型,SomeClass
因此它不允许添加。一个例外是null
可以表示任何类型的Object
.
回答您的评论:虽然您无法添加到Collection
,但不能将其描述为只读,因为仍然可以删除 Objects
。
要允许添加Objects
,您需要使用已知类型:
Vector<SomeClass> v = new Vector<SomeClass>();
问题基本上是通过声明它是一个集合v
或它的一个子类。编译器无法对容器实际保存的特定类型做出任何假设,即使分配是在同一行上完成的。据编译器所知,可能已创建为. 这就是为什么它拒绝将实例(或其他任何东西)放入集合中。但是,您可以从中获取元素。Vector<? extends SomeClass>
SomeClass
new Vector<SomeClass>()
v
new Vector<SubClassOfSomeClass>()
SomeClass
SomeClass
如果您希望能够将元素放入集合中,则声明v
为Vector<? super SomeClass>
,这样您就可以说它是容器SomeClass
或其超类之一。然后编译器知道一个SomeClass
实例肯定适合这样的集合。
但是,您不能从该集合中获取元素SomeClass
,因为编译器对其中元素的类型一无所知(除了它是 的某个超类SomeClass
)。根据它的定义,v
它也可能只是Object
s 的集合。
这被称为put/get 原则,在其他类似的帖子中也有详细讨论。
你的问题解释应该没有问题。我在以下代码中理解了您的问题。
import java.util.*;
class Test
{
int x;
}
public class Demo
{
public static void main(String args[])
{
Vector<Test> vect = new Vector<Test>();
Test t1 = new Test();
Test t2 = new Test();
t1.x = 10;
t2.x = 20;
vect.add(t1);
vect.add(t2);
for(Test t : vect)
{
System.out.println(t.x);
}
}
}
我在Vector Play With中读到了这种类型的噱头。