java - 如何将对象数组转换为整数数组

标签 java

这是一个有点人为的例子来理解我遇到的情况,但基本上,我有一个对象数组,实际上包含整数数组,我正试图这样转换它。这是模拟这种情况的代码片段:

Object[] foo = new Object[3];
foo[0] = new int[] { 1, 2, 3 };
foo[1] = new int[] { 4, 5, 6 };
foo[2] = new int[] { 7, 8, 9 };
int[][] bar = (int[][]) foo;

当我尝试这样做时,我得到异常 Exception in thread "main"java.lang.ClassCastException: [Ljava.lang.Object;不能转换为 [[I

有没有办法在不复制数组的情况下做到这一点(我可能不想这样做,因为 foo 在生产中会非常大)?如果不是,为什么不呢?

最佳答案

您不能通过强制转换来更改 Java 对象的固有类型。这包括数组。对象的类型在分配对象时是固定的,不能更改。

因此,将 Object[] 转换为 int[][] 将永远行不通。

在这种情况下,虽然 int[][]Object[] 的子类型,但这不足以在运行时允许类型转换。 JLS ( 5.5.3. Checked Casts at Run Time) 中的实际规则是这样的:

"Here is the algorithm to check whether the run-time type R of an object is assignment compatible with the type T which is the erasure (§4.6) of the type named in the cast operator. If a run-time exception is thrown, it is a ClassCastException." ...

"If R is a class representing an array type RC[], that is, an array of components of type RC:"

  • "If T is an array type TC[], that is, an array of components of type TC, then a run-time exception is thrown unless one of the following is true:"

    • "TC and RC are the same primitive type."

    • "TC and RC are reference types and type RC can be cast to TC by a recursive application of these run-time rules for casting."

在这种情况下,TC 是 int[],RC 是 Object 并且 Object 不能 转换为 整数[]。因此你会得到一个异常(exception)。

为了说明为什么这必须发生,考虑这个(假设的)例子:

   Object[] foo = new Object[3];
   foo[0] = new Object();
   int[][] bar = /* foo */
   int[] mystery = bar[0];

假设可以“强制转换”foo 的值,那么mystery 变量应该指向什么?它不能是 int[] 因为我们没有分配一个。它不能是 Object 实例,因为那样会破坏静态类型。

事实上,“cast”必须是非法的,否则 Java 的静态类型系统就会分崩离析。


The difference between your example and mine is that foo is not actually an array of arrays of integers, whereas in my case it is. Why can the VM not see the "actual" type of the object?

重点是静态类型(主要)是由编译器而非 JVM 强制执行的。虽然 JVM 可以(理论上)确定类型在运行时是正确的(如果不正确则抛出异常),编译器不能这样做,因为它无法确定一般类型是什么成为。


Unfortunately I'm not actually creating the array myself. I'm getting it from another function and the Object[] rather than int[][] is, as far as I can tell, the side effect of some serialization that I have no control over.

不幸的是,您必须复制数组...或将其用作 Object[] 并将元素转换为 int[] 才能使用它们;例如

Object[] foo = new Object[3];
foo[0] = new int[] { 1, 2, 3 };
foo[1] = new int[] { 4, 5, 6 };
foo[2] = new int[] { 7, 8, 9 };
...
int nine = ((int[]) (foo[2]))[2];

Java 中没有“相信我,这真的是一个int[][]”选项。

如果这是序列化的副作用,那么序列化就被破坏了……在某种意义上。当然,标准 Java 对象序列化协议(protocol)/实现不会发生这种情况。 保留对象的类型...除非您在 readObject/writeObject 方法等中显式覆盖它们。

关于java - 如何将对象数组转换为整数数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18839906/

相关文章:

java - 如何使用 java 在 mongoDB 中插入图像?

java - 如何从InputStreamReader读取整数

java - 我得到了 java.util.ArrayList.throwIndexOutOfBoundsException 和一个堆栈跟踪,其中没有我的代码

java - java 随机字节转int

java - 防止根据当前值插入数据库

java - 检查单选按钮是否选择了特定 Activity

java - 一个服务、一个线程、一个 Activity 和一个静态 ArrayList

java - 使用 JOOX 过滤来自 REST 端点的 xml 数据

java - 使用 spring 将属性直接 Autowiring 到 bean 中?

java - 检索 Java 数组中的 DataFrame 值