这个方法声明有什么区别:
public static <E extends Number> List<E> process(List<E> nums){
Run Code Online (Sandbox Code Playgroud)
和
public static List<Number> process(List<Number> nums){
Run Code Online (Sandbox Code Playgroud)
你会在哪里使用前者?
pol*_*nts 49
第一个允许processa List<Integer>,a List<Double>等.第二个不允许.
Java中的泛型是不变的.它们不像数组一样协变.
也就是说,在Java中,Double[]是子类型Number[],但是List<Double>不是子类型List<Number>.List<Double>然而,A 是一个List<? extends Number>.
泛型不变的原因很充分,但这也是为什么extends和super类型通常需要用于子类型的灵活性.
super和extends有限通配符extends消费者super"原则Ber*_*t F 12
后一种方法(没有 这种方法<E extends Number>)只接受一个确切类型的参数,List<Number>并且它总是返回一个List<Number>.例如,它不会接受List<Integer>.
在前者的方法(将一个用 <E extends Number>)是一种通用的方法,这意味着它可以接受不同类型的ListS和它将返回同一类型的List,只要Lists为名单东西延伸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
}
Run Code Online (Sandbox Code Playgroud)
请参阅Java教程中的泛型课程中的通配符章节中的类似说明:http:
//java.sun.com/docs/books/tutorial/java/generics/subtyping.html
另请参见如何将继承对象列表转换为Java中的对象集合? 这两个问题都是关于泛型和子类型的,例如是否List<Integer>是List<Number>(它不是!!!)的子类型.