什么是使用Collection <! - ?扩展SomeAbstractClass - >而不是Collection <someabstractclass> </someabstractclass>

时间:2013-10-16 09:59:21

标签: java generics

因此,假设我们有一个Java应用程序,其中包含一个名为SomeAbstractClass的抽象类,以及至少10个超类的子类。

Collection<? extends SomeAbstractClass>的方式中使用这个抽象超类在泛型中的用法是什么,而不仅仅是使用Collection<SomeAbstractClass>

也许我错过了仿制药中非常基本的东西。

4 个答案:

答案 0 :(得分:4)

这两个声明之间的区别:

Collection<? extends A> c1;
Collection<A> c2;

c2是否可以包含A或任何子类的实例,但是c1可以包含某个未知但是特定的A(或A)子类或任何未知类的子类的实例。

您无法将项目添加到c2,因为编译器不知道它是什么类型,只有当您获得一个时它才可以转换为A。

此外,你不能将c1指定(即强制转换)为c2 - c1不是c2类型的子类。

答案 1 :(得分:1)

泛型中的通配符用于Collection Type,通常不用于存储的元素。

例如,想象一个采用参数List<Number>的方法。

public void calculateSum(List<Number> numbers) {
    for (Number n: numbers) {
       // calculate Sum
   }
}

现在,如果我们想通过传递List<Integer>来计算整数之和,如下所示。 (请注意,IntegerNumber

的子类
List<Integer> integers= new ArrayList<Integer>();
//Populate collection
calculateSum(integers);  //Error

即使Integers是[{1}} Number的子类型不是List<Integers>的子类型,这也不会起作用。请注意,List<Number>仍然可以存储List<Number>IntegerFloat等。

因此,要使用通用方法计算任何类型Double的总和,我们使用通配符,如下所示

Number

如果类型扩展public void calculateSum(List<? extends Number> numbers) { for (Number n: numbers) { // calculate Sum } }

,这将计算任何类型数字的总和

答案 2 :(得分:0)

以下是not true in generics

Collection<? extends SomeAbstractClass> 
              ^
              |
              |
Collection<SomeAbstractClass>

Collection<? extends SomeAbstractClass>Collection<SomeAbstractClass>是完全不同的类型,不相关。

请注意,

  

给出两个具体类型A和B(例如,Number和Integer),   MyClass与MyClass没有任何关系,无论是否   不是A和B是相关的。

例如,List<Integer>不是List<Number>的子类型,即使Integer是Number的子类型。

答案 3 :(得分:-2)

在你的情况下它没有区别,因为类型是抽象的,但一般Collection<SomeClass>可以包含SomeClass及其所有子类,而Collection<? extends SomeClass>不能包含SomeClass但只有它子类。

你可以自己试试。

List<Number> foo = new ArrayList<>();
foo.add(Integer.valueOf(0));

工作时

List<? extends Number> foo = new ArrayList<>();
foo.add(Integer.valueOf(0));

没有。它显示错误"The method add(capture#1-of ? extends Number) in the type List<capture#1-of ? extends Number> is not applicable for the arguments (Integer)"