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


71

以下代码有什么问题?

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

该代码在最后一行有以下错误:

线程“主”中的异常java.lang.ClassCastException:[Ljava.lang.Object; 无法转换为[Ljava.lang.Integer;

Answers:


95

罗斯,您也可以使用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视为的数组ObjectInteger[]是的子类型,Object[]Object[]不是的子类型Integer[]

并且以下内容也不会给出ClassCastException

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

1
为什么Arrays.copyOf从不抛出ClassCastException?
克瓦斯(Kvass)2014年

因为在那里,我将Integer []。class作为参数。我想在内部,每个对象都将转换为Integer并添加到Integer数组中
namalfernandolk 2014年

是的,通常在使用泛型时会遇到这种情况,而这种答案是无用的。
托马什Zato -恢复莫妮卡

24

您不能将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在执行分配时已经必须检查类型安全性,但是在仅读取元素时就不必检查类型安全性。
乔恩·斯基特

4
原因很简单。如果允许您将Object []强制转换为Integer [],则JVM将永远无法确定数组中对象的实际类型,因为作为Object []对数组的旧引用可能仍然存在。由于它永远无法确定它是什么,因此每次都必须对一次数组中对象的每次访问进行类型检查。如果类型检查失败,它将在与原因完全不同的地方引发异常。
福特队长

14

或执行以下操作:

...

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

  return integerArray;

}

这个Integer []等于int []的integerArray吗?我想不是。需要拆箱。
2013年

我最喜欢这个
Jared'7

1
仅适用于integerList为列表或ArrayList的情况。不适用于“经典”数组tho :(
f1v3

1
您也可以使用Arrays.asList(objectArray).toArray(new Integer[objectArray.length]),但是这样做与namalfernandolk的答案完全相同,而没有必要的开销
Xerus

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

您尝试将对象数组转换为整数数组。你做不到。不允许这种类型的垂头丧气。

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


1
当用Java完成转换时,Java编译器以及Java运行时会检查是否可以进行转换,并在可能的情况下抛出错误。

当涉及对象类型的转换时,instanceof应通过测试以使分配通过。在您的示例中,结果为
Object[] a = new Object[1]; boolean isIntegerArr = a instanceof Integer[]
如果执行sysout上述行的a,它将返回false;否则,结果为false。
因此,在投射前尝试check实例会有所帮助。因此,要解决该错误,您可以添加'instanceof'检查

使用以下代码行: 请注意,如果Object数组包含除Integer之外的任何其他项,则上述代码将失败。
(Arrays.asList(a)).toArray(c);

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.