【问题标题】:Fundamentals on Generics泛型基础
【发布时间】:2013-03-04 11:57:30
【问题描述】:

为什么以下不起作用?

Vector<? extends SomeClass> v = new Vector<SomeClass>();  
SomeClass e = new SomeClass();  
v.add(e);  

我得到一个编译错误:

类型中的方法add(capture#1-of ? extends SomeClass) 向量不适用于 参数(SomeClass)

【问题讨论】:

标签: java generics


【解决方案1】:

从一个类型扩展的带有generic wildcards 的集合不允许您添加到该Collection

由于编译器不知道您尝试添加的SomeClass 的确切类型,因此它不允许添加。一个例外是null 对象,它可以表示任何类型的Object

回答您的评论:虽然您不能添加Collection,但它不能被描述为只读,因为它仍然可以删除 Objects.

要允许添加Objects,您需要使用已知类型:

Vector<SomeClass> v = new Vector<SomeClass>();

【讨论】:

  • @Jim 您仍然可以按索引从“wildcared”向量中删除。
  • 使用Vector&lt;? super SomeClass&gt; 确实允许您添加到集合中。
【解决方案2】:

问题基本上是通过将v 声明为Vector&lt;? extends SomeClass&gt; 你说它是SomeClass 的集合它的一个子类。即使对new Vector&lt;SomeClass&gt;() 的赋值是在同一行完成的,编译器也无法对容器实际保存的特定类型做出任何假设。据编译器所知,v 可能已创建为new Vector&lt;SubClassOfSomeClass&gt;()。这就是为什么它拒绝将SomeClass 实例(或其他任何东西)放入 到集合中。但是,您可以从中获取 SomeClass 元素。

如果您希望能够放入元素到集合中,则将v 声明为Vector&lt;? super SomeClass&gt;,这样您就可以说它是SomeClass 的容器或 它的超类之一。然后编译器知道SomeClass 实例肯定适合这样的集合。
但是,您不能从该集合中获取 SomeClass 元素,因为编译器对其中的元素类型一无所知(除了它是SomeClass 的某个超类)。根据v 的定义,它也可能只是Objects 的集合。

这被简称为put/get 原则,在this等其他帖子中也有详细讨论。

【讨论】:

    【解决方案3】:

    这已解释here。这样声明的列表实际上是一个只读列表,但它比普通的List&lt;AbstractClass&gt; 列表更灵活。

    如果您想使用抽象类作为模板,只需像这样直接使用它:List&lt;SomeClass&gt; list

    考虑阅读Java language specification,有很多关于泛型逻辑的信息。

    【讨论】:

      【解决方案4】:

      你的问题解释应该没有问题。我在以下代码中理解了您的问题。

      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看到了这种噱头。

      【讨论】:

      • OP 没有要求对向量操作进行初学者培训。您的帖子绝对不是对 OP 问题的回答。而且发布不相关的答案并不是推广博客的最佳方式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 1970-01-01
      • 1970-01-01
      • 2021-09-29
      • 2010-11-27
      • 1970-01-01
      相关资源
      最近更新 更多