![](/img/trans.png)
[英]What is the difference between List<Number> and List<? extends Number>?
[英]What is the difference between <E extends Number> and <Number>?
這個方法聲明有什么區別:
public static <E extends Number> List<E> process(List<E> nums){
和
public static List<Number> process(List<Number> nums){
你會在哪里使用前者?
第一個允許process
List<Integer>
, List<Double>
等。第二個不允許。
Java中的泛型是不變的。 它們不像數組一樣協變。
也就是說,在Java中, Double[]
是Number[]
的子類型,但List<Double>
不是List<Number>
的子類型。 但是List<Double>
是List<? extends Number>
List<? extends Number>
。
泛型不變的原因很充分,但這也是extends
和super
類型通常需要用於子類型靈活性的原因。
super
一些用法,並extends
了有界通配符 extends
消費者super
”的原則 后一種方法 ( 沒有 <E extends Number>
)只接受List<Number>
類型的參數,並且它總是返回List<Number>
。 例如,它不接受List<Integer>
。
前一種方法 ( 帶有 <E extends Number>
)是一種通用的方法 ,這意味着它可以接受不同類型的List
S和將返還相同種類的List
,只要在List
s的東西擴展列表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
另請參見如何將繼承對象列表轉換為Java中的對象集合? 這兩個問題都是關於泛型和子類型的,例如List<Integer>
是否是List<Number>
的子類型(它不是!!!)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.