Java泛型中的List

深入理解Java泛型中的list extends base>

本文將詳細(xì)解答關(guān)于java泛型中l(wèi)ist extends base>的使用疑問(wèn)。 在java中,泛型提供了強(qiáng)大的類型安全機(jī)制,但其一些特性也容易造成困惑,例如list extends base>就常常讓開(kāi)發(fā)者感到棘手。

我們假設(shè)sub是base的子類

public class base { }  public class sub extends base { }

理解list super base>相對(duì)容易:

list<? super base> list1 = new arraylist<>(); list1.add(new sub()); list1.add(new base());

list1可以接受base及其子類的實(shí)例。這是因?yàn)? super base表示list中元素的類型是base的超類型(包括base本身)。 任何base的子類都可以向上轉(zhuǎn)型為base或其超類型,因此添加操作是允許的。

立即學(xué)習(xí)Java免費(fèi)學(xué)習(xí)筆記(深入)”;

然而,list extends base>的行為則截然不同:

list<? extends base> list2 = new arraylist<>();

為什么我們不能向list2添加任何元素,即使是base實(shí)例也不行呢? 這并非因?yàn)樽宇愔g不能互相轉(zhuǎn)換,關(guān)鍵在于list extends base>的含義。

list extends base>表示這是一個(gè)list,其元素類型是base的子類型,但這子類型究竟是base本身還是sub,甚至是其他繼承自base的類,我們無(wú)法確定。 這意味著編譯器無(wú)法驗(yàn)證添加任何元素的操作是否安全。 如果我們嘗試添加一個(gè)base對(duì)象,編譯器無(wú)法保證這個(gè)list的實(shí)際類型(可能是list)能夠容納base對(duì)象。 同樣的道理,添加sub對(duì)象也存在同樣的問(wèn)題,因?yàn)閘ist的實(shí)際類型可能不是list

為了更好地理解,我們可以參考下面的例子:

class Bag<T> {     public void set(T t) {}     public T get() { return null; } }  class Fruit {} class Apple extends Fruit {} class Pear extends Fruit {}  // ...  (Bag類的使用示例,與答案中一致) ...

這個(gè)例子清晰地展現(xiàn)了? extends和? super在讀寫操作上的限制,加深了我們對(duì)list extends base>的理解,它只允許讀取操作,而不允許寫入操作。因?yàn)榫幾g器無(wú)法在編譯時(shí)確定list的實(shí)際類型,所以任何寫入操作都可能導(dǎo)致運(yùn)行時(shí)異常。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊14 分享