extends
通配符式聲明 List<? extends Number> foo3
意味著以下每一條皆為合法語句:
List<? extends Number> foo3 = new ArrayList<Number>(); // Number "extends" Number (in this context)
List<? extends Number> foo3 = new ArrayList<Integer>(); // Integer extends Number
List<? extends Number> foo3 = new ArrayList<Double>(); // Double extends Number
-
讀 - 若有以上聲明阎毅,則對List foo3進行讀操作時會出現(xiàn)以下情形:
- 可以讀取
Number
類型的數(shù)據(jù)署驻,因為可以賦予foos的列表均包含Number
類型或其子類型的數(shù)據(jù)诡挂。 - 無法讀取
Integer
類型的數(shù)據(jù)凉翻,因為foo3可能指向List<Double>
類型的數(shù)據(jù)蜗帜。 - 無法讀取
Double
類型的數(shù)據(jù)来惧,因為foo3可能指向List<Integer>
類型的數(shù)據(jù)洽蛀。
- 可以讀取
-
寫 - 若有以上聲明耙蔑,則對List foo3進行寫操作(add)時會出現(xiàn)以下情形:
- 無法增添
Integer
類型的數(shù)據(jù)结序,因為foo3
可能指向List<Double>
類型的數(shù)據(jù)。 - 無法增添
Double
類型的數(shù)據(jù)纵潦,因為foo3
可能指向List<Integer>
類型的數(shù)據(jù)徐鹤。 - 無法增添
Number
類型的數(shù)據(jù)垃环,因為foo3
可能指向List<Integer>
類型的數(shù)據(jù)。
- 無法增添
無法向List<? extends T>
添加任何對象返敬,因為無法保證變量具體指向的是什么類型的List
遂庄,從而無法保證目標(biāo)List
允許添加何種類型的對象。唯一能保證的是可以從中讀出一個T
類型或其子類型的數(shù)據(jù)劲赠。
super
List <? super T>
.
通配符式聲明 List<? super Integer> foo3
意味著以下每一條皆為合法語句:
List<? super Integer> foo3 = new ArrayList<Integer>(); // Integer is a "superclass" of Integer (in this context)
List<? super Integer> foo3 = new ArrayList<Number>(); // Number is a superclass of Integer
List<? super Integer> foo3 = new ArrayList<Object>(); // Object is a superclass of Integer
-
讀 - 若有以上聲明涛目,則對List foo3進行讀操作時會出現(xiàn)以下情形:
- 無法讀取
Integer
類型的數(shù)據(jù),因為foo3可能指向List<Number>
或List<Object>
類型的數(shù)據(jù)凛澎。 - 無法讀取
Number
類型的數(shù)據(jù)霹肝,因為foo3可能指向List<Object>
類型的數(shù)據(jù)。 - 只能讀取
Object
類型或Object
子類型的數(shù)據(jù)(但無法確定是那個子類)塑煎。
- 無法讀取
-
寫 - 若有以上聲明沫换,則對List foo3進行寫操作(add)時會出現(xiàn)以下情形:
- 可以增添
Integer
類型的數(shù)據(jù),因為示例代碼中的所有list
均允許增添Integer
類型的數(shù)據(jù)最铁。 - 可以增添
Integer
子類型的數(shù)據(jù)讯赏,因為示例代碼中的所有list
均允許增添Integer
子類型的數(shù)據(jù)。 - 無法增添
Double
類型的數(shù)據(jù)冷尉,因為foo3可能指向ArrayList<Integer>
類型的數(shù)據(jù)漱挎。 - 無法增添
Number
類型的數(shù)據(jù),因為foo3可能指向ArrayList<Integer>
類型的數(shù)據(jù)雀哨。 - 無法增添
Object
類型的數(shù)據(jù)磕谅,因為foo3可能指向ArrayList<Integer>
類型的數(shù)據(jù)。
- 可以增添
PECS
記住一個口訣: "Producer Extends, Consumer Super"(PECS).
-
"Producer Extends" - 如果一個
List
需要生產(chǎn)T
類型的數(shù)據(jù)(你想要從list中讀取T類型數(shù)據(jù))雾棺,你需要將其聲明成? extends T
, e.g.List<? extends Integer>
膊夹。但你無法向其中增添數(shù)據(jù)。 -
"Consumer Super" - 如果你需要一個消費T類型數(shù)據(jù)的
list
(向其中增添T類型數(shù)據(jù))垢村,你需要將其聲明成? super T
, e.g.List<? super Integer>
割疾。但是你將不知道會從中讀取到何種類型的數(shù)據(jù)嚎卫。 - 如果你需要從對
List
進行讀和寫操作嘉栓,則不要使用通配符式的聲明方式,e.g.List<Integer>
拓诸。
===> 翻譯于StackOverflow