什么是< ?扩展E>

时间:2016-06-26 05:46:55

标签: java generics collections wildcard

在使用泛型时我遇到了声明< ? extends E>。 如果我举例说明集合界面的addAll方法。

它的声明如下:

   interface Collection<E> {
      public boolean addAll(Collection<? extends E> c);
  }

所以从上面的addAll声明中我已经理解了(从不同来源读取)

  • ? extends E表示添加集合的所有成员也可以使用任何类型的元素作为E的子类型

让我们来看看这个例子:

List<Integer> ints = new ArrayList<Integer>();
ints.add(1);
ints.add(2);

List<? extends Number> nums = ints; // now this line works
/*
 *without using ? syntax above line did not use to compile earlier 
 */
List<Double> doubleList = new ArrayList<Double>();
doubleList.add(1.0);
nums.addall(doubleList); // compile time error 

错误:

  

方法addall(List&lt; Double&gt;)未定义类型List&lt;捕获#1?扩展数字&gt;

我还阅读了O&#39; Reilly的Java Generics and Collections&#39;

  

通常,如果结构包含具有表单类型的元素?扩展E,我们可以从结构中获取元素,但我们不能将元素放入结构中。

所以我的问题是,当我们无法用此修改事物时,有什么用呢?只是为了从该集合中获取元素,如果它是一个子类型?

2 个答案:

答案 0 :(得分:2)

  

所以我的问题是当我们不能用这个修改东西时,有什么用呢?只是为了从该集合中获取元素,如果它是一个子类型?

是的,这是正确的。只是为了从中获取元素。

请注意,Collection<? extends Number>变量的类型,而不是集合本身的类型。通配符语法的含义更类似于特定集合必须匹配的模式,而不是“对象X是T类型”的类型。

如果Java没有通配符,那么你所表达的内容就会受到很大限制。例如,通用addAll方法只接受完全相同组件类型的集合。

答案 1 :(得分:0)

这意味着addAll方法允许扩展E类的任何对象集合。 例如,如果G扩展E,则可以向此集合添加G数组。