[英]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
的調用。 因此,無論方法x
中list
的類型如何,對add
的調用都將保留類型安全性。
繼承關系表示為“是”:您的SubClass
是ParentClass
,而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.