为了账号安全,请及时绑定邮箱和手机立即绑定

为什么有界类型参数会出现“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 关注
  • 70 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信