簡體   English   中英

關於Java中通配符的簡單說明

[英]A simple clarification about Wild Cards in Java

我剛剛閱讀了有關Java中的通配符的信息,並且正在研究一個案例,其中有2個類,ParentClass和SubClass繼承自它。 (ParentClass,SubClass擴展ParentClass)

現在,我寫這些行。

List<? super ParentClass> list1 = new ArrayList<ParentClass>();
list1.add(new SubClass());

我不明白為什么要編譯和運行。 第2行是否應該導致編譯錯誤,因為我試圖將ParentClass的子級添加到應該僅包含ParentClass的父級的列表中?

謝謝!

類型List<? super ParentClass> List<? super ParentClass>意思是“某些最多為ParentClass的未知類型的列表”。 如果您有接受此類型參數的方法,則可以向其傳遞類型為List<ParentClass>List<GrandparentClass> ,..., List<Object>

void x(List<? super ParentClass> list) {
    list.add(new SubClass());
}

這些類型的任何列表都將允許使用SubClass類型的參數進行add的調用。 因此,無論方法xlist的類型如何,對add的調用都將保留類型安全性。

繼承關系表示為“是”:您的SubClassParentClass ,而ParentClass是其超類的實例, ParentClass 。因此,在編碼時,您始終可以在ParentClass或其任何祖先的任何位置設置SubClass

SubClass subClass = new SubClass();
ParentClass aParent = subClass;

根據Java多態性功能,可以將您的子類對象分配給Parent類的引用類型。 在這里,它將子類分配給ParentClass類型的引用。

這就是為什么它起作用

嗨,

[This]( 什么是PECS(生產者擴展了消費者超級用戶)? )確實可以幫助您理解。 有一個稱為PECS的規則。 生產者擴展和消費者超級。 該規則應該已經包含在通配符的Java教程中,因為如果沒有此規則,對我而言,對有界通配符的理解似乎是不完整的。

從本質上講,這意味着如果您只想從List中讀取(而不是寫入其中),請使用

 List<? extends ParentClass> 

它表示您將獲得作為ParentClass或ParentClass子類型的對象。 此外,這意味着List處於只讀模式。

如果您想“放入”列表而不是從列表中讀取內容,則可以將列表聲明為

 List<? Super ParentClass> 

您可以添加ParentClass或其類型的類型。 但是別無他法。

此外,編寫了以下代碼,並

1   List<? super ChildClass > list1 = new ArrayList<ChildClass>();
2       list1.add(new GrandChildAbstract());
3      list1.add(new ChildClass());
4     list1.add(new Abstractclass());
5      
6       ChildClass ch=  list1.get(0);
7       Abstractclass ch = list1.get(0);
8       
9       List<? extends ChildClass> list2 = new ArrayList<ChildClass>();
10       list2.add(new GrandChildAbstract());
11       list2.add(new ChildClass());
12      list2.add(new Abstractclass());

Eclipse的編譯時間錯誤地出現在第4、6、7和10、11、12行。這清楚地表明,必須在只讀和僅寫入上下文中理解超級綁定通配符。

好吧,看來您對這些條款感到困惑。

當你說

List<? super ParentClass> list1;

您說的是,list1將接受所有列表類型為ParentClass或更高的列表。

此代碼無效,因為SubClass不是ParentClass的超類。

List<? super ParentClass> list1 = new ArrayList<SubClass>();

當你寫

List<? super ParentClass> list1 = new ArrayList<ParentClass>();

等於

List<ParentClass> list1 = new ArrayList<ParentClass>();

並且一旦SubClass是ParentClass的子類型:

list1.add(new SubClass());

運行正常。

ps:對不起,我的英語不好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM