3 回答

TA貢獻(xiàn)1836條經(jīng)驗(yàn) 獲得超5個(gè)贊
通過(guò)聲明,GenericMethod<? super ClassB>
您將聲明該類型是未知類型,它是 ClassB(或 ClassB 本身)的超類。并要求編譯器只允許將這種未知類型的子類型添加到列表中。
編譯器知道的唯一兼容子類型是 ClassB 和 ClassB 的任何子類型。創(chuàng)建實(shí)例時(shí),通常最好避免使用通配符。
對(duì)于方法參數(shù),通配符使您可以更靈活地接受哪些內(nèi)容。使用PECS
(生產(chǎn)者=擴(kuò)展,消費(fèi)者=超級(jí)) 來(lái)確定使用哪個(gè)。?

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超9個(gè)贊
該? super
子句是下限通配符。但界限是在推斷的類型參數(shù)上,而不是對(duì)可以傳遞給采用該泛型類型參數(shù)的方法的參數(shù)類型的限制。
當(dāng)您說(shuō) 時(shí)<? super ClassB>
,您表明類型參數(shù)可以是ClassB
或 任何超類型,例如ClassA
或Object
。
編譯器必須將該add
方法視為可以是以下任何簽名:
add(Object t) add(ClassA t) add(ClassB t)
ClassA
(如果直接從另一個(gè)類繼承而不是繼承的話,可能還有其他類型Object
)。
編譯器必須拒絕將 aClassA
作為 的參數(shù),add
因?yàn)轭愋蛥?shù)可能被推斷為ClassB
。GenericMethod<ClassB>
將 a 分配給變量是合法的genericMethod
。
GenericMethod<? super ClassB> genericMethod = new GenericMethod<ClassB>();
但是能夠?qū)?a 傳遞ClassA
給需要 a 的方法是沒(méi)有意義的ClassB
。
事實(shí)上,這就是菱形算子 - 的推斷ClassB
。
您的困惑在于兩個(gè)概念的合并:允許哪些類型參數(shù)以及使用類型參數(shù)的方法中允許哪些類型的對(duì)象。使用通配符會(huì)限制類型參數(shù),但該方法仍然接受類型參數(shù)或子類型的類型。

TA貢獻(xiàn)2036條經(jīng)驗(yàn) 獲得超8個(gè)贊
我承認(rèn)這有點(diǎn)違反直覺(jué),但從編譯器的角度來(lái)看,這是有道理的。
假設(shè)您以這種方式定義一個(gè)列表:
List<? super ClassB> myList;
你得到了
ClassB extends ClassA; ClassC extends ClassA;
你能做嗎?
ClassA a = new ClassC(); myList.add (a);//does not compile
不,有幾個(gè)原因。首先是因?yàn)樽罱K在運(yùn)行時(shí),參數(shù)化類型變成了具體的單一類型。因此,實(shí)際上您不能將A 類對(duì)象與 B 類對(duì)象混合。
其次,因?yàn)榫幾g器必須檢查您插入的任何內(nèi)容是否可強(qiáng)制轉(zhuǎn)換為ClassB。因此,只需添加一個(gè) ClassB 對(duì)象(或他的子類型),即可履行合同。但事實(shí)并非總是如此!ClassA 對(duì)象不能是 ClassB 的超類型。
即對(duì)象“a”實(shí)際上是一個(gè)ClassC對(duì)象!
這就是為什么你不能添加超類型。所以它只允許您添加 ClassB 對(duì)象 - 或子類型 -
如果將對(duì)象“a”轉(zhuǎn)換為 ClassB,則會(huì)編譯,但在運(yùn)行時(shí)會(huì)失敗并出現(xiàn)ClassCastException:
ClassA a = new ClassC(); myList.add((ClassB) a); //Compiles but fails at runtime
同時(shí),通配符與super結(jié)合,可以作為方法的形參。IE:
void printValues (List<? super ClassB> list)
這種方式允許對(duì)超級(jí) B 類集合的處理進(jìn)行一般化,從而使以下調(diào)用成為可能:
List<Object> lo; List<ClassA> la; ... printValues (lo); printValues (la);
在本例中,定義使用通配符,例如 <? super ClassB>,更有意義一些。
添加回答
舉報(bào)