<e extends =“”number =“”>和<number>?</number> </e>之间有什么区别?

时间:2010-05-05 02:28:44

标签: java generics

此方法声明之间有什么区别:

public static <E extends Number> List<E> process(List<E> nums){

 public static List<Number> process(List<Number> nums){

你会在哪里使用前者?

2 个答案:

答案 0 :(得分:48)

第一个允许process的{​​{1}},List<Integer>等。第二个不允许。

Java中的泛型是不变的。它们不像数组一样协变。

也就是说,在Java中,List<Double>Double[]的子类型,但Number[]不是List<Double>的子类型。但是,List<Number>List<Double>

泛型不变的原因很充分,但这也是List<? extends Number>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>的子类型(它不是!!!)。