<E extends Number>和<Number>之间有什么区别?

unj*_*nj2 36 java generics

这个方法声明有什么区别:

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>.

泛型不变的原因很充分,但这也是为什么extendssuper类型通常需要用于子类型的灵活性.

也可以看看


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>(它不是!!!)的子类型.