关于java:List <Number>和List <有什么区别?扩展Number>?

What is the difference between List<Number> and List<? extends Number>?

关于Java泛型,我有一个非常基本的问题。我认为List<Number>List<? extends Number>都是同质的。我是对的还是我缺少的基本知识?


泛型类型更加书呆子。

<? extends Number>表示Number或未知的子类。如果获得这样的值,它将是Number,但是由于您不知道哪个有效,因此无法给出此类型的值。

区别在于参数和返回值。

1
2
3
4
5
6
7
8
9
10
11
12
13
List<Number> numbers = new ArrayList<Number>();
Number n = 1;
numbers.add(n); // ok.
n = numbers.get(0); // ok
numbers.add(1); // ok.

List<? extends Number> numbers2 = new ArrayList<Double>();
numbers2.add(n); // not ok
n = numbers2.get(0); // ok

List<? super Number> numbers3 = new ArrayList<Serializable>();
numbers3.add(n); // ok
n = numbers3.get(0); // not ok.

super在一些地方用于表示该类型可以是超级类型。例如

在集合中,此方法表示比较器需要能够比较相同类型或任何超级类型。

1
public static < T > void sort(List< T > list, Comparator<? super T> c)

这意味着您可以拥有

1
2
3
Comparator<Number> comparesAnyNumbers = ...
List<Integer> ints = ...
Collections.sort(ints, comparesAnyNumbers);


泛型是编译时语言的功能,这意味着它们在运行时不存在。
在通用机制中,对于编译时检查,它们不是同质的,即,如果要在通用类型中使用多态。

以下内容为您提供了一个编译时错误,尽管这似乎是一个有效的定义:

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

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

有效。此外,您不能在右侧使用通配符类型:

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

不会被编译。


List<Number>-> Number s(或Number的实例)列表

List<? extends Number>->列出扩展Number

的任何类型