extends
通配符式聲明 List<? extends Number> foo3 意味著以下每一條皆為合法語(yǔ)句:
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
-
讀 - 若有以上聲明,則對(duì)List foo3進(jìn)行讀操作時(shí)會(huì)出現(xiàn)以下情形:
- 可以讀取
Number類(lèi)型的數(shù)據(jù),因?yàn)榭梢再x予foos的列表均包含Number類(lèi)型或其子類(lèi)型的數(shù)據(jù)。 - 無(wú)法讀取
Integer類(lèi)型的數(shù)據(jù),因?yàn)閒oo3可能指向List<Double>類(lèi)型的數(shù)據(jù)。 - 無(wú)法讀取
Double類(lèi)型的數(shù)據(jù),因?yàn)閒oo3可能指向List<Integer>類(lèi)型的數(shù)據(jù)。
- 可以讀取
-
寫(xiě) - 若有以上聲明,則對(duì)List foo3進(jìn)行寫(xiě)操作(add)時(shí)會(huì)出現(xiàn)以下情形:
- 無(wú)法增添
Integer類(lèi)型的數(shù)據(jù),因?yàn)?code>foo3可能指向List<Double>類(lèi)型的數(shù)據(jù)。 - 無(wú)法增添
Double類(lèi)型的數(shù)據(jù),因?yàn)?code>foo3可能指向List<Integer>類(lèi)型的數(shù)據(jù)。 - 無(wú)法增添
Number類(lèi)型的數(shù)據(jù),因?yàn)?code>foo3可能指向List<Integer>類(lèi)型的數(shù)據(jù)。
- 無(wú)法增添
無(wú)法向List<? extends T>添加任何對(duì)象,因?yàn)闊o(wú)法保證變量具體指向的是什么類(lèi)型的List,從而無(wú)法保證目標(biāo)List允許添加何種類(lèi)型的對(duì)象。唯一能保證的是可以從中讀出一個(gè)T類(lèi)型或其子類(lèi)型的數(shù)據(jù)。
super
List <? super T>.
通配符式聲明 List<? super Integer> foo3 意味著以下每一條皆為合法語(yǔ)句:
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
-
讀 - 若有以上聲明,則對(duì)List foo3進(jìn)行讀操作時(shí)會(huì)出現(xiàn)以下情形:
- 無(wú)法讀取
Integer類(lèi)型的數(shù)據(jù),因?yàn)閒oo3可能指向List<Number>或List<Object>類(lèi)型的數(shù)據(jù)。 - 無(wú)法讀取
Number類(lèi)型的數(shù)據(jù),因?yàn)閒oo3可能指向List<Object>類(lèi)型的數(shù)據(jù)。 - 只能讀取
Object類(lèi)型或Object子類(lèi)型的數(shù)據(jù)(但無(wú)法確定是那個(gè)子類(lèi))。
- 無(wú)法讀取
-
寫(xiě) - 若有以上聲明,則對(duì)List foo3進(jìn)行寫(xiě)操作(add)時(shí)會(huì)出現(xiàn)以下情形:
- 可以增添
Integer類(lèi)型的數(shù)據(jù),因?yàn)槭纠a中的所有list均允許增添Integer類(lèi)型的數(shù)據(jù)。 - 可以增添
Integer子類(lèi)型的數(shù)據(jù),因?yàn)槭纠a中的所有list均允許增添Integer子類(lèi)型的數(shù)據(jù)。 - 無(wú)法增添
Double類(lèi)型的數(shù)據(jù),因?yàn)閒oo3可能指向ArrayList<Integer>類(lèi)型的數(shù)據(jù)。 - 無(wú)法增添
Number類(lèi)型的數(shù)據(jù),因?yàn)閒oo3可能指向ArrayList<Integer>類(lèi)型的數(shù)據(jù)。 - 無(wú)法增添
Object類(lèi)型的數(shù)據(jù),因?yàn)閒oo3可能指向ArrayList<Integer>類(lèi)型的數(shù)據(jù)。
- 可以增添
PECS
記住一個(gè)口訣: "Producer Extends, Consumer Super"(PECS).
-
"Producer Extends" - 如果一個(gè)
List需要生產(chǎn)T類(lèi)型的數(shù)據(jù)(你想要從list中讀取T類(lèi)型數(shù)據(jù)),你需要將其聲明成? extends T, e.g.List<? extends Integer>。但你無(wú)法向其中增添數(shù)據(jù)。 -
"Consumer Super" - 如果你需要一個(gè)消費(fèi)T類(lèi)型數(shù)據(jù)的
list(向其中增添T類(lèi)型數(shù)據(jù)),你需要將其聲明成? super T, e.g.List<? super Integer>。但是你將不知道會(huì)從中讀取到何種類(lèi)型的數(shù)據(jù)。 - 如果你需要從對(duì)
List進(jìn)行讀和寫(xiě)操作,則不要使用通配符式的聲明方式,e.g.List<Integer>。
===> 翻譯于StackOverflow