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

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

為什么有界類型參數會出現“java.lang.ClassCastException:

為什么有界類型參數會出現“java.lang.ClassCastException:

qq_遁去的一_1 2023-08-16 10:05:12
由于 java 沒有通用數組,因此我使用將對象數組轉換為類型參數的常規技巧。當我有一個正式的類型參數時,這工作得很好,<T>但當我使用有界類型參數時卻不行<T extends something>。使用正式類型遵循代碼效果很好public class Deck <T> {    private T [] cards;    private int size;    public Deck () {        cards = (T []) new Object[52];        size = 0;    }}public class BlackJackGame {    Deck<BlackJackCard> deck;    public BlackJackGame() {        deck = new Deck<>();        populate (deck);        deck.shuffle();    }}public class BlackJackCard extends Card {}以下使用有界類型的代碼會引發錯誤public class Deck <T extends Card> {    private T [] cards;    private int size;    public Deck () {        cards = (T []) new Object[52];        size = 0;    }}public class BlackJackGame {    Deck<BlackJackCard> deck;    public BlackJackGame() {        deck = new Deck<>();        populate (deck);        deck.shuffle();    }}public class BlackJackCard extends Card {}Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LCard;    at Deck.<init>(Deck.java:10)    at BlackJackGame.<init>(BlackJackGame.java:5)
查看完整描述

1 回答

?
不負相思意

TA貢獻1777條經驗 獲得超10個贊

這個例子讓我想起了早期,當我在“Effective java”一書中閱讀有關泛型的內容時......


首先,這是java泛型的黃金法則:不要混合數組和泛型,因為你有很好的機會生成不安全的代碼。您的代碼將泛型(例如 T、T extends Card)與數組(例如 T [] 卡)混合在一起。然后,您在運行時得到不安全的代碼。


這是一種安全的方法(首選列表而不是數組):


class Deck <T extends Card> {

    private List<T> cards;


    public Deck () {

        cards = new ArrayList()<>;

    }

}

現在,要回答你的問題,你應該首先回到 java 的一些基礎知識:

1- 數組是共變結構

2-泛型是不變的結構

3-元素類型在數組中具體化(reification)

4- 參數類型在通用中被擦除(類型擦除)

不用擔心,先把可怕的概念放在一邊,看看你的例子發生了什么:

  • 形式類型 T 在運行時被刪除。

  • 這意味著它在字節碼中被完全刪除。

  • 在第一個示例中,T 只是被替換為 Object,因為它是最接近它的類(就繼承而言),所以,

cards = (T []) new Object[52]

被翻譯成

cards = (Object []) new Object[52];

這是安全的。

  • 在第二個示例中, T 綁定到 Card 并且它變成 ,因此,是最接近它的類(就繼承而言),因此,

cards = (T []) new Object[52]

被翻譯成

cards = (Card []) new Object[52];

由于 Object 不是 Card 的子類型,因此您遇到了運行時強制轉換異常。


查看完整回答
反對 回復 2023-08-16
  • 1 回答
  • 0 關注
  • 124 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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