为什么以下内容不起作用?
Vector<? extends SomeClass> v = new Vector<SomeClass>();
SomeClass e = new SomeClass();
v.add(e); 我得到一个编译错误,即:
方法添加(捕获#1-of?)在类型向量中扩展SomeClass)不适用于参数(SomeClass)
发布于 2013-03-04 12:10:46
问题在于,通过将v声明为Vector<? extends SomeClass>,您可以说它是SomeClass的集合或它的一个子类。编译器不能对容器实际保存的特定类型做出任何假设,即使分配给new Vector<SomeClass>()的任务是在同一行上完成的。正如编译器所知道的那样,v可能被创建为new Vector<SubClassOfSomeClass>()。这就是为什么它拒绝将 SomeClass实例(或其他相关内容)放到集合中的原因。但是,可以将从SomeClass元素中提取出来。
如果您希望能够将中的元素放到集合中,那么就将v声明为Vector<? super SomeClass>,其中您说它是一个SomeClass容器或它的一个超类。然后编译器知道SomeClass实例肯定适合这样的集合。
但是,不能从该集合中获取一个SomeClass元素,因为编译器对其中元素的类型一无所知(只是它是SomeClass的某个超类)。根据v的定义,它可能只是Object的集合。
简而言之,这被称为put/get原则,在其他类似这的文章中也有详细讨论。
发布于 2013-03-04 12:00:17
从类型扩展的带有通用通配符的集合不允许向该Collection添加。
由于编译器不知道您要添加的SomeClass的确切类型,所以它不允许它。这方面的例外是一个null对象,它可以表示任何类型的Object。
要回答您的评论:虽然不能添加到Collection中,但不能将其描述为只读,因为仍然可以删除Objects。
要允许添加Objects,您需要使用已知类型:
Vector<SomeClass> v = new Vector<SomeClass>();发布于 2013-03-04 12:00:32
这是解释这里。这样声明的列表实际上是一个只读列表,但它比普通的List<AbstractClass>列表更灵活。
如果您想使用抽象类作为模板,只需直接使用它,如:List<SomeClass> list。
考虑阅读Java语言规范,有很多关于泛型逻辑的信息。
https://stackoverflow.com/questions/15201041
复制相似问题