泛型中extends和super的區(qū)別

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
  1. - 若有以上聲明,則對(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ù)。
  2. 寫(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ú)法向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
  1. - 若有以上聲明,則對(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))。
  2. 寫(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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容