https://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html
上述说明:
List<? extends Number> a
将适用于Number,Integer,Double列表,以及任何作为数字子类的内容。
但是在Java 8中,当我尝试:
List<Number a
使用Number及其任何子类。
是我,还是仿制药过于复杂和不清楚?
答案 0 :(得分:0)
我们假设你正在编写一个接受Number
列表的通用方法,因为Number
是该方法工作所需的最小接口。
如果您编写如下方法:
public void myMethod(List<Number> list) {...}
如果用户传入List<Number>
,则可以正常工作,但是他们无法传递List<Integer>
,例如because generics are invariant。这意味着无法将List<Integer>
分配给List<Number>
。
但是,让我们说,在您的方法中,您只是从列表中取出内容,并且只关心它们是 Number
的任何子类(i.e. the list is a producer)。为了您的目的,用户可以传递List<Integer>
。
这是有界通配符的来源。
写作:
public void myMethod(List<? extends Number> list) {...}
您可以让用户传入List<Integer>
,因为它可以分配给List<? extends Number>
。但是,如果从列表中检索元素,您仍然可以确定它是Number
。
但一个重要的区别是,您无法再将Number
添加到此列表中。由于列表可能实际上是List<Integer>
,因此添加Number
将不是类型安全的。
答案 1 :(得分:0)
List<Number>
不意味着它不能包含Integer
- 您可以在此列表中添加Integer
以及Double
,甚至两者都在同一个清单中。
无法执行的操作将List<Integer>
分配到List<Number>
。如果您被允许这样做会发生什么:
List<Integer> intList = new ArrayList<Integer>();
List<Number> numberList = intList; // suppose this was possible
Number myNum = new Double(...);
numberList.add(myNum); // it's OK to put a Number in List<Number>
Integer myInt = intList.get(0); // myInt now equals myNum, I have Integer that's in fact a Double. Oops.