5

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

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

也许我错过了泛型中一些非常基本的东西。

4

4 回答 4

4

这两种声明的区别:

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

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

您不能将项目添加到 c2,因为编译器不知道它是什么类型,只有当您得到一个项目时,它才能被强制转换为 A。

此外,您不能将 c1 分配(即强制转换)给 c2 - c1 不是 c2 类型的子类。

于 2013-10-16T10:19:10.390 回答
1

泛型中的通配符用于集合类型,通常不用于存储的元素。

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

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

现在,如果我们想通过传递来计算整数的总和,List<Integer>如下所示。(注意这Integer是 的子类Number

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

这将不起作用,因为即使Integersis 的子类型不是Number List<Integers>List<Number>类型。请注意,List<Number>仍然可以存储Integer,FloatDouble

因此,为了有一个通用的方法来计算任何类型的总和,Number我们使用通配符如下

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

如果类型扩展,这将计算任何类型的数字的总和Number

于 2013-10-16T10:55:28.527 回答
0

以下在泛型中不正确

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

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

注意,

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

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

于 2013-10-16T10:22:41.233 回答
-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)"

于 2013-10-16T10:03:08.910 回答