为什么强制转换Object []数组是错误的? [英] Why is it wrong to cast Object[] array?

查看:41
本文介绍了为什么强制转换Object []数组是错误的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Java泛型编程非常陌生.

I'm very new to generic programming in Java.

我不明白为什么无法创建通用类型的数组.

I don't understand why arrays of generic type can't be created.

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

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

If generic type means that the generic placeholder Twill be replaced by a class name during run-time, what prevents us from creating an array having generic references?

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

After a bit of searching, I found a workaround

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

尽管我找到了解决方案,但我仍然无法理解是什么阻碍了创建通用数组.假设我创建了一个返回Object数组的函数.

Although I found a solution, I still fail to understand what prevents from creating a generic array. Suppose I create a function that returns an Object array.

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

然后拨打电话

And then make the call

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

提供一个 ClassCastException .但为什么?它看起来与我将Object数组转换为T数组的第一行代码相似吗?

gives a ClassCastException . But why? Doesn't it look similar to first line of code where I cast Object array into T array?

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

如果没有小故障,那为什么不呢?

If this went without a glitch why didn't that?

推荐答案

部分要点是从另一角度看待它.您不能(String [])新对象[10] ;因为 Object 数组是不是 String 数组.因为

Part of the point is to look at it the other way around. You cannot do (String[]) new Object[10]; because an Object array is not a String array. Because

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 .

...is trying to assign an Integer to a String, which shouldn't be allowed in the first place. So this code fails when you cast the Object[] to a String[]. That code has to throw a ClassCastException somewhere.

对于Java来说,甚至在最初发明泛型之前就一样.接受所有第一.然后继续使用泛型.

This is all the same for Java even before generics were invented in the first place. Accept all that first. Then move on to generics.

现在,实现Java泛型的方式 意味着在编译代码时, T 被静默重写为 Object .因此,静默地允许 T [] array =(T [])new Object [10] ,因为实际上它已被重写为 Object [] array = new Object [10] .但是,一旦将其取出,就会出问题.例如,

Now, the way Java generics are implemented means that when you compile the code, T is silently rewritten to Object. So T[] array = (T[]) new Object[10] is silently allowed, because it actually gets rewritten to Object[] array = new Object[10]. But as soon as you take it out, things go wrong. For example,

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

如果您调用 String [] array = newArray(),则将在调用站点而不是 newArray()内获得 ClassCastException .代码>.这就是为什么Java在(T [])new Object [10] 处给您警告的原因,而该警告很可能稍后会导致真正的 ClassCastException .

if you call String[] array = newArray(), you'll get a ClassCastException at the call site, not within newArray(). This is why Java gives you a warning at (T[]) new Object[10], and that warning may well lead to a real ClassCastException later on.

通常来说,不要混合使用数组和泛型.解决所有问题的方法是正确使用 List .

Generally speaking, don't mix arrays and generics. The way around all this is to use a List properly.

这篇关于为什么强制转换Object []数组是错误的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆