java - 为什么强制转换 Object[] 数组是错误的?

标签 java arrays object generics

我对 Java 泛型编程还很陌生。

我不明白为什么不能创建通用类型的数组。

T[] a = new T[size]; //why does this give an error?

如果泛型类型意味着泛型占位符 T 将在运行时被类名替换,是什么阻止我们创建具有泛型引用的数组?

经过一番搜索,我找到了解决方法

T[] a = (T[])new Object[size];   //I don't get how this works?

虽然我找到了解决方案,但我仍然无法理解是什么阻止了创建通用数组。 假设我创建了一个返回对象数组的函数。

public Object[] foo(){
        return new Object[12];
}

然后调用

String[] a = (String[])foo();

给出一个 ClassCastException 。但为什么? 它看起来不像我将 Object 数组转换为 T 数组的第一行代码吗?

 T[] a = (T[])new Object[size];

如果一切顺利,那为什么没有呢?

最佳答案

部分要点是反过来看。你不能做 (String[]) new Object[10] ;因为 Object数组不是 String大批。因为

String[] array = new String[10];
array[0] = "foo";
String foo = array[0];

很好,但是

Object[] objectArray = new Object[10];
objectArray[0] = 10;
String[] stringArray = (String[]) objectArray;
String foo = stringArray[0];

...正在尝试分配 IntegerString ,这首先不应该被允许。所以当你转换 Object[] 时这段代码失败了到 String[] .该代码必须抛出 ClassCastException某处。

即使在泛型被发明之前,Java 也是如此。 首先接受所有这些。 然后继续学习泛型。

现在,Java 泛型的实现 意味着当您编译代码时,T被默默地重写为 Object .所以T[] array = (T[]) new Object[10]被默默地允许,因为它实际上被重写为 Object[] array = new Object[10] .但是一旦你把它拿出来,事情就不对了。例如,

private static <T> T[] newArray() {
   return (T[]) new Object[10];
}

如果您调用 String[] array = newArray() ,你会得到一个 ClassCastException在调用站点,不在 newArray() 内.这就是为什么 Java 在 (T[]) new Object[10] 给你一个警告。 ,并且该警告很可能会导致真正的 ClassCastException稍后。

一般来说,不要混用数组和泛型。解决所有这些问题的方法是使用 List

关于java - 为什么强制转换 Object[] 数组是错误的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32587816/

相关文章:

java - 构造函数的开闭原则

java - java中如何对二维数组的列求和

java - 使用 onkeydown 方法或覆盖 onbackbuttonpressed 时,Android 后退按钮会卡住

java - 生产者-消费者模型;存储缓冲区进入和退出时间

java - 检查数组中的特定元素是否包含某个字符串。然后删除该元素

Javascript:对象中的函数根据声明语法自动命名(或不命名)——为什么?

java - 为Android应用程序设置声音

c - 如何检查指向结构数组的指针在c中是否为空?

java - 什么时候声明对象?

actionscript-3 - 获取 Actionscript-3 中对象的 "key"