第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

試圖理解超級(jí)通配符在Java泛型中的作用

試圖理解超級(jí)通配符在Java泛型中的作用

溫溫醬 2023-11-01 20:57:24
我正在閱讀這篇文章來(lái)了解通配符在泛型中的作用super。我明白如何extends運(yùn)作,但我很難理解super我有一個(gè)擴(kuò)展ClassA,使ClassB超ClassA類ClassB。如果我正確理解這篇文章,則將<? super ClassB>允許任何屬于ClassB.我有以下代碼GenericMethod.javapublic class GenericMethod<T> {    private List<T> list;    public GenericMethod() {        list = new ArrayList<>();    }    public void add(T t) {        list.add(t);    }    public T get(int index) {        return list.get(index);    }}Driver.javapublic class Driver {    public static void main(String[] args) {        GenericMethod<? super ClassB> genericMethod = new GenericMethod<>();        ClassA classA = new ClassA();        genericMethod.add(classA); // Compile-time error here    }}錯(cuò)誤The method add(capture#1-of ? super ClassB) in the type GenericMethod<capture#1-of ? super ClassB> is not applicable for the arguments (ClassA)我不明白我哪里錯(cuò)了。當(dāng)我實(shí)例化該類時(shí)GenericMethod,我已經(jīng)聲明它將接受任何帶有聲明的超類型值。因此,類內(nèi)部應(yīng)該接受所有擴(kuò)展的類。ClassB<? super ClassB>TGenericMethodClassB那么為什么該add方法會(huì)拋出編譯時(shí)錯(cuò)誤呢?該方法不應(yīng)該add已經(jīng)知道它正在傳遞一個(gè)完全兼容的類型嗎?
查看完整描述

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è)。?


查看完整回答
反對(duì) 回復(fù) 2023-11-01
?
慕妹3146593

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超9個(gè)贊

? super子句是下限通配符。但界限是在推斷的類型參數(shù)上,而不是對(duì)可以傳遞給采用該泛型類型參數(shù)的方法的參數(shù)類型的限制。

當(dāng)您說(shuō) 時(shí)<? super ClassB>,您表明類型參數(shù)可以是ClassB或 任何超類型,例如ClassAObject。

編譯器必須將該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ù)或子類型的類型。


查看完整回答
反對(duì) 回復(fù) 2023-11-01
?
慕桂英3389331

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>,更有意義一些。


查看完整回答
反對(duì) 回復(fù) 2023-11-01
  • 3 回答
  • 0 關(guān)注
  • 131 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)