【发布时间】:2011-02-15 17:59:14
【问题描述】:
这个方法声明有什么区别:
public static <E extends Number> List<E> process(List<E> nums){
和
public static List<Number> process(List<Number> nums){
你会在哪里使用前者?
【问题讨论】:
这个方法声明有什么区别:
public static <E extends Number> List<E> process(List<E> nums){
和
public static List<Number> process(List<Number> nums){
你会在哪里使用前者?
【问题讨论】:
第一个允许List<Integer>、List<Double> 等的process。第二个不允许。
Java 中的泛型是不变的。它们不像数组那样是协变的。
也就是说,在 Java 中,Double[] 是 Number[] 的子类型,但 List<Double> 不是 List<Number> 的子类型。但是,List<Double> 是 List<? extends Number>。
泛型保持不变是有充分理由的,但这也是为什么extends 和super 类型对于子类型化灵活性通常是必要的。
super 和extends 用于有界通配符的一些用法extends消费者super”原则【讨论】:
<E extends Number> E process(E elt) vs Number process(Number elt)
后一种方法(没有<E extends Number>的那个)只接受一个完全类型为List<Number>的参数,并且它总是
返回List<Number>。例如,它将不接受List<Integer>。
前一种方法(with<E extends Number>)是一个generic method,意味着它可以接受不同类型的@987654329 @s
它会返回相同类型的List,只要Lists 是 something 的列表
扩展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> 的子类型(不是!!!)。
【讨论】: