1
Object arr = new int[]{1,2,3};
arr = (int[])arr; 

int someArr [] = (int[])arr;

for(int i:arr)  // compilation error
     System.out.println(i);

for(int i:someArr) //works fine
     System.out.println(i);

为什么第二行的演员表不会将 arr 转换为 int 数组?我在第 4 行收到一个编译错误,上面写着“只能迭代一个数组或一个实例java.lang.Iterable”。调试时,在第 2 行,变量快照显示带有索引值的 arr。

4

7 回答 7

5

该语句arr = (int []) arr首先尝试将存储的值arr转换为int []. 然后,为了能够进行赋值,它尝试将右侧的结果转换为=左侧变量的类型。由于左侧变量的类型是Object,因此int []被转换回Object. 所以arr留下来Object

我们从中学到什么?您不能更改变量的声明类型。绝不。特别是,您不能通过为它分配任何其他类型的东西来做到这一点。赋值有效并且赋值被强制转换为变量的声明类型,或者赋值失败。变量的类型永远不会改变。

于 2013-04-27T08:57:16.970 回答
1

铸造只能在使用它的行中起作用。在下一行,编译器会忘记它,只看到 的定义arr,它仍然是Object。如果您不想创建新变量,可以在需要告诉编译器做什么的地方添加强制转换。

Object arr = new int[]{1,2,3};

for(int i : (int[])arr) // cast when using the object
    System.out.println(i);
于 2013-04-27T08:56:49.040 回答
1

只能遍历数组或java.lang.Iterable.

这是指编译时(即静态)而不是运行时(即动态)类型。

arr的编译时间是Object,这意味着你不能迭代它,不管它的运行时类型是什么

于 2013-04-27T08:57:32.150 回答
1

声明的arrbeing类型Object,编译器不确定它是否引用数组,因此不知道如何迭代它。

为什么第二行的演员表不会将 arr 转换为 int 数组?

对于引用类型(例如Object),强制转换不会转换,而只是检查引用是否指向给定类型的对象。如果检查成功,则可以使用该类型的所有功能(如果转换不成功,则抛出 ClassCastException)。

于 2013-04-27T09:01:27.667 回答
1

因为你正在做向下铸造。在向下转换中,您必须执行从 Object 到 Int 的显式转换。你在做。像这样

for(int i:someArr) //它工作正常。

因此,您必须将此 arr 显式转换为 int。

在向上转换中,您没有进行显式转换。它默认提供隐式转换。

for(对象 i=somearr)

在这里,Object 是所有类的超类。

你明白我的意思了吗?

于 2013-04-27T09:03:04.797 回答
0

arr 是一个Object. Java不能神奇地cast那样。

for(int i:someArr )  // compile
                 System.out.println(i);
于 2013-04-27T08:51:03.540 回答
0

您的arr投射不会改变. arrtype 仍然Object是你声明的那样,你不能迭代Object.

于 2013-04-27T08:52:39.783 回答