将对象数组转换为整数数组错误。

80

以下代码有什么问题?

Object[] a = new Object[1];
Integer b=1;
a[0]=b;
Integer[] c = (Integer[]) a;

代码在最后一行出现以下错误:

异常 in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; 无法转换为 [Ljava.lang.Integer;

5个回答

112

Ross,你也可以使用Arrays.copyof()或Arrays.copyOfRange()

Integer[] integerArray = Arrays.copyOf(a, a.length, Integer[].class);
Integer[] integerArray = Arrays.copyOfRange(a, 0, a.length, Integer[].class);

在这里,导致出现 ClassCastException 的原因是您不能将一个 Integer 数组视为 Object 数组。 Integer[]Object[] 的子类型,但 Object[] 不是 Integer[]

而且以下内容也不会引发 ClassCastException

Object[] a = new Integer[1];
Integer b=1;
a[0]=b;
Integer[] c = (Integer[]) a;

2
为什么 Arrays.copyOf 永远不会抛出 ClassCastException 异常? - Kvass
1
因为我在那里将Integer[].class作为参数传递。我想,在内部,每个对象都会转换为Integer并添加到Integer数组中。 - ironwood
是的,通常在使用泛型时会遇到这种情况,因此这个答案是无用的。 - Tomáš Zato
如果你有这样的数组 --> Object[] a = {1, 2, "b", 'c'}; 那么你会得到一个错误,提示"元素类型不匹配..."。 - AkSh

28

你无法将一个Object数组强制转换为一个Integer数组。 你需要循环遍历a的所有元素并逐个进行类型转换。

Object[] a = new Object[1];
Integer b=1;
a[0]=b;
Integer[] c = new Integer[a.length];
for(int i = 0; i < a.length; i++)
{
    c[i] = (Integer) a[i];
}

编辑:我相信这个限制背后的原因是在进行类型转换时,JVM希望确保运行时的类型安全性。由于一个Objects数组除了Integers之外还可以是任何东西,所以JVM无论如何都必须像上面的代码一样(逐个查看每个元素)。语言设计者决定他们不想让JVM这样做(我不确定为什么,但我相信有很好的理由)。

然而,你可以将子类型数组强制转换为超类型数组(例如,Integer[]转换成Object[])!


3
数组是协变的这一事实意味着当JVM执行赋值操作时,它已经必须检查类型安全性 - 但是在仅读取元素时则无需检查。 - Jon Skeet
4
原因很简单。如果允许将Object[]转换为Integer[],那么JVM就无法确定数组中对象的实际类型,因为旧引用仍然可以作为Object[]存在。每次访问数组中的对象时,它都必须进行类型检查,因为它永远不知道它是什么。如果类型检查失败,它会在与原因完全不相关的地方抛出异常。 - Captain Ford

15

或者执行以下操作:

...

  Integer[] integerArray = new Integer[integerList.size()];
  integerList.toArray(integerArray);

  return integerArray;

}

这个 Integer[] 类型的 integerArray 是否等同于 int[] 类型?我猜不是。需要进行拆箱操作。 - Akh
1
只有当 integerList 是 List 或 ArrayList 时才有效.. 对于“经典”数组不起作用 :( - f1v3
1
你也可以使用 Arrays.asList(objectArray).toArray(new Integer[objectArray.length]),但这与 namalfernandolk 的回答 完全相同,只是多了不必要的开销。 - xeruf

5
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;

您试图将一个对象数组转换为整数数组。这是不允许的向下转型。

您可以创建一个整数数组,然后将第一个数组的每个值复制到第二个数组中。


1
在Java中进行类型转换时,Java编译器和Java运行时会检查转换是否可行,如果不可行则抛出错误。

涉及对象类型的强制转换时,必须通过 instanceof 测试才能进行赋值。在您的示例中,结果是
Object[] a = new Object[1]; boolean isIntegerArr = a instanceof Integer[] Object[] a = new Object[1]; boolean isIntegerArr = a instanceof Integer[]
如果你在上述行中执行sysout命令,它将返回false;
尝试在转换之前进行检查的实例可能会有所帮助。因此,要修复错误,您可以添加“instanceof”检查。
OR
使用以下代码行:
(Arrays.asList(a)).toArray(c);

请注意,如果对象数组包含除整数以外的任何条目,则以上代码将失败。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接