【问题标题】:Why is it legal to cast an Object array to a generics array?为什么将 Object 数组强制转换为泛型数组是合法的?
【发布时间】:2019-09-04 20:49:59
【问题描述】:

当我尝试将对象数组转换为自定义数据类型(类)数组时,我得到 ClassCastException,但是当我将对象数组转换为泛型数组时,没有观察到此类错误;此外,如果我将自定义数据类型(类)作为类型参数传递,则也不会抛出 ClassCastException。

我做了几件事:

  • 首先,我创建了一个名为TestClass 的自定义数据类型。然后我尝试创建一个对象数组并将其转换为 TestClass TestClass[] b = (TestClass[]) new Object[100];
    • 结果:ClassCastException
  • 我使 Main 类(执行实验的 main() 函数)接受称为 Item 的类型参数(泛型)。接下来是一行代码this.a = (Item[]) new Object[100];,其中a 是一个实例变量,定义为Item[] a
    • 结果:退出代码 0
  • 现在,我在main(String[] args) 中添加了一行代码:Main<TestClass> m = new Main<TestClass>(); 请注意,我将TestClass 作为类型参数传递,因此在构造函数中我们面临的情况与第一个实验设置中的情况几乎相同,因此我期待ClassCastException
    • 结果:存在代码 0

整个Main类供进一步参考(假设TestClass已定义):

public class Main<Item>{
    Item a[];
    TestClass b[];
    public Main(){
        //this.b = (TestClass[]) new Object[100]; (errors disappear when this line is commented out, otherwise ClassCastException is thrown)
        this.a = (Item[]) new Object[100];
    }
    public void doStuff(){
        System.out.println(Arrays.toString(this.a));
        System.out.println(Arrays.toString(this.b));
    }
    public static void main(String[] args) {
        Object a = new Object();
        Main<TestClass> m = new Main<TestClass>(); //TestClass passed as type argument, should cause problems in the constructor
        m.doStuff();
    }

抱歉没有使用正确的 Java 约定,我只是在试验:)

【问题讨论】:

  • 注意您在使用此代码时会收到的编译器警告。

标签: java arrays generics casting


【解决方案1】:

由于type erasureItem被擦除为Object,所以你的代码变成了

public class Main {
    Object a[];

    ...
    this.a = (Object[]) new Object[100];
    ...
}

不出所料,演员阵容成功。

现在如果你添加例如

TestClass[] b = m.a;

main,编译器需要插入一个演员表

TestClass[] b = (TestClass[]) m.a;

那个 会失败,因为 m.a 真的是 Object[]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 2014-08-05
    相关资源
    最近更新 更多