此方法声明之间有什么区别:
public static <E extends Number> List<E> process(List<E> nums){
和
public static List<Number> process(List<Number> nums){
你会在哪里使用前者?
答案 0 :(得分:48)
第一个允许process
的{{1}},List<Integer>
等。第二个不允许。
Java中的泛型是不变的。它们不像数组一样协变。
也就是说,在Java中,List<Double>
是Double[]
的子类型,但Number[]
不是List<Double>
的子类型。但是,List<Number>
是List<Double>
。
泛型不变的原因很充分,但这也是List<? extends Number>
和extends
类型通常需要用于子类型灵活性的原因。
super
和super
对有界通配符的一些用法extends
消费者extends
”原则答案 1 :(得分:12)
后一种方法(一个没有 <E extends Number>
)只会接受一个类型为List<Number>
的参数,并且它总是会
返回List<Number>
。例如,不接受List<Integer>
。
以前的方法(一个 <E extends Number>
)是 generic method ,这意味着它可以接受不同的List
的类型
只要List
是某些的列表,它就会返回相同类型的List
延伸Number
,例如List<Integer>
。
示例:
import java.util.ArrayList;
import java.util.List;
public class ProcessGenerics {
List<Number> listNumber = new ArrayList<Number>();
List<Integer> listInteger = new ArrayList<Integer>();
List<Double> listDouble = new ArrayList<Double>();
public static
List<Number> processWithoutExtends(List<Number> nums){ return nums; }
List<Number> resultN = processWithoutExtends(listNumber); // OK
//List<Integer> resultI = processWithoutExtends(listInteger); // compile-error - method not applicable
//List<Double> resultD = processWithoutExtends(listDouble); // compile-error - method not applicable
public static <E extends Number>
List<E> processWithExtends(List<E> nums){ return nums; }
List<Number> resultN2 = processWithExtends(listNumber); // OK
List<Integer> resultI2 = processWithExtends(listInteger); // OK
List<Double> resultD2 = processWithExtends(listDouble); // OK
}
请参阅Java教程中的泛型课程中的通配符章节中的类似说明:
http://java.sun.com/docs/books/tutorial/java/generics/subtyping.html
另请参阅 How to cast a list of inheriting objects to a collection of objects in Java? 这两个问题都与泛型和子类型有关,例如:是否List<Integer>
是List<Number>
的子类型(它不是!!!)。