亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java泛型:返回有界泛型類型

Java泛型:返回有界泛型類型

哈士奇WWW 2021-07-24 19:01:08
我遵循了這段代碼:public <T extends ParentException> T managedException(Exception cause) {            if(ExceptionA.class.isInstance(cause)) {        return ExceptionA.class.cast(cause);    } else if(ExceptionB.class.isInstance(cause)) {        return ExceptionB.class.cast(cause);    } else if(ExceptionC.class.isInstance(cause)){        return ExceptionC.class.cast(cause);    } else {        return new ExceptionD(cause.getMessage(), cause);    }}在這里ExceptionA,ExceptionB,ExceptionC,ExceptionD是兒童ParentException。在編譯時,我得到了錯誤:incompatible types: ExceptionA cannot be converted to Tincompatible types: ExceptionB cannot be converted to Tincompatible types: ExceptionC cannot be converted to Tincompatible types: ExceptionD cannot be converted to T但是,如果我將代碼更改為:@SuppressWarnings("unchecked")public <T extends ParentException> T managedException(Exception cause) {            if(ExceptionA.class.isInstance(cause)) {        return (T) ExceptionA.class.cast(cause);    } else if(ExceptionB.class.isInstance(cause)) {        return (T) ExceptionB.class.cast(cause);    } else if(ExceptionC.class.isInstance(cause)){        return (T) ExceptionC.class.cast(cause);    } else {        return (T) new ExceptionD(cause.getMessage(), cause);    }}它沒有編譯錯誤。正如 SO 線程的這個答案中提到的:How do I make the method return type generic? ,T允許使用 with進行轉換,并且在此線程中給出了另一個指針:Java 泛型:泛型類型僅定義為返回類型。但我的問題是:當T有界并且所有返回的對象都落入指定的界限時,為什么我需要使用類型轉換?
查看完整描述

3 回答

?
慕哥9229398

TA貢獻1877條經驗 獲得超6個贊

你在做什么是錯誤的。這就是您收到錯誤的原因。你可以調用你的方法,ExceptionC exceptionC=managedException(ExceptionD d)你最終會得到一個(ExceptionC) exceptionD;強制轉換并且強制轉換它會掩蓋錯誤,但你會在運行時得到它。


將您的方法更改為:


public ParentException managedException(Exception cause) {        

    if(ExceptionA.class.isInstance(cause)) {

        return ExceptionA.class.cast(cause);

    } else if(ExceptionB.class.isInstance(cause)) {

        return ExceptionB.class.cast(cause);

    } else if(ExceptionC.class.isInstance(cause)){

        return ExceptionC.class.cast(cause);

    } else {

        return new ExceptionD(cause.getMessage(), cause);

    }

}

這里不需要泛型。所有這些異常也是 ParentExceptions,所以你可以直接返回它們。當您考慮它時,您正在嘗試使該方法返回不同的類型。不能那樣做,因為如果你有一個從這個方法初始化的變量,你需要知道結果是什么。而且您知道結果將是 ParentException 但您不知道那是哪種父異常。


其背后的原因是,您的方法如果編寫為不返回 ParentException - 它返回 T (子類)。您可以返回不同類型的子類,而不是您想要獲取的子類。


在一個更簡單的例子中,如果我們有:


class A {}


class B extends A{  };


class C extends A{  };


public  <T extends A> T test() {        

        return (T) new B();

}   

我們可以調用它C c=test();我們實際上嘗試強制轉換(C) new B();這是不兼容的但是我們已經屏蔽了它并且我們在運行時得到了異常


查看完整回答
反對 回復 2021-07-29
?
浮云間

TA貢獻1829條經驗 獲得超4個贊

因為

ExceptionA a = managedException(new ExceptionB());

將與ClassCastException. Java 推斷T為,ExceptionA并且您的代碼將進入這種B情況,這將導致錯誤的強制轉換。

Java 說它ExceptionC不是 a是正確的,T因為它T也可以是任何其他子類型ParentException。


查看完整回答
反對 回復 2021-07-29
  • 3 回答
  • 0 關注
  • 169 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號