集合中的泛型

2022-09-03 13:23:09

这是我的程序。我不确定为什么我收到编译时错误。

import java.util.ArrayList;
import java.util.List;

public class Test {
public static void main(String[] args) {
    List< ? extends Number > list = new ArrayList<Integer>();

    list.add(6); // Compile Time Error

    System.out.println(list);

  }
}

但以下程序工作正常

import java.util.ArrayList;
import java.util.List;

public class Test {
public static void main(String[] args) {
    List< ? super Number > list = new ArrayList<Number>();

    list.add(6); 

    System.out.println(list);

    }
}

来自 Eclipse 的错误:

以下是 Eclipse 的错误描述:

类型 List 中的方法 add(int, capture#1-of ? extends Number) 不适用于参数 (int)


答案 1

这是因为您在第一种情况下所做的不是类型安全的。您已声明为 “的某个子类”,然后尝试在其中插入 a。绝对不能保证与基础列表的实际运行时类型兼容。编译器会在这里阻止你,因为你正在做的事情没有任何意义listListNumberIntegerInteger

举个极端的例子:

List< ? extends Object > list = new ArrayList<Integer>();
list.add("Hello, World!");

如果这有效,你会有一个在里面!List<Integer>String

如果你真的想让它工作,你必须通过强制转换告诉编译器你知道你在做什么:

((List<Integer>)list).add(6);

但即便如此,您仍然会收到有关类型安全的警告。

第二种情况之所以有效,是因为该列表保证是“Number的某个超类”。 是 的子类,因此它可以隐式转换为任何超类(包括其自身),因此不存在值与列表的实际类型不兼容的风险。IntegerNumberNumber

有关更多信息,您可能需要阅读协方差和逆方差之间的差异。


答案 2

不能向 具有 作为其泛型类型的一部分的 任何内容添加任何内容。List? extends ...

让我们来看看这个:

List< ? extends Number > list = new ArrayList<Integer>();

请注意,您正在使用的实际值是 .应该不可能在此列表中放置不是 .但是,该类型将允许您例如将 a 添加到列表中,因为它还扩展了 .ListArrayList<Integer>IntegerList<? extends Number>DoubleDoubleNumber

有关更多详细信息,请参阅Angelika Langer的Java泛型常见问题解答中的以下内容:哪些方法和字段可以通过通配符参数化类型的参考变量访问/无法访问?


推荐