我对 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];
...正在尝试分配 Integer
到 String
,这首先不应该被允许。所以当你转换 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/