为什么将Object[]类型的变量作为Object[]元素转换为Object[][]时会出错?

huangapple go评论69阅读模式
英文:

Why it's wrong when the variable of Object[] as elements of Object[] transfrom to Object[][]

问题

以下是翻译好的部分:

我想要将object[]用作object[]的元素,以将其转换为Object[][],但无法运行。所以我想知道为什么它是错误的。以及如何在给定一个数字k的情况下创建一个k维数组。

这是错误的代码:

public static void main(String[] args) {
    Object[] s = new Object[3];
    s[0] = new Integer[1];
    s[1] = new Integer[1];
    s[2] = new Integer[1];
    Object m = s;
    Integer[][] t = (Integer[][])m;

    System.out.println(Arrays.toString(t));
}
英文:

I want to use object[] as the element of object[] to transform it to Object[][], but it can't run. So I want to know why it is wrong. And how can I achieve that giving a number k, and create a array that is k dimensional.

Here is the wrong code:

public static void main(String[] args) {
         Object[] s = new Object[3];
         s[0] = new Integer[1];
         s[1] = new Integer[1];
         s[2] = new Integer[1];
         Object m = s;
         Integer[][] t = (Integer[][])m;
        
        System.out.println(Arrays.toString(t));
    }

答案1

得分: 3

Object[][] 类型表示数组只能包含其他 Object[] 实例。

但是 Object[] 也可以包含不是 Object 数组的内容。

请注意,当你从一个引用类型强制转换为另一个引用类型时,不会发生任何值转换,对象的实际类型也不会改变。发生的只是运行时系统会检查对象的实际运行时类型是否与你要进行转换的类型兼容


为了说明为什么必须这样做,考虑以下示例:

Object[] s = new Object[2];
s[0] = new Integer[1];
Integer[][] t = (Integer[][]) s;   // ONE
s[1] = "Hello";
Integer[] u = t[1];                // TWO

如果(假设!)在 "ONE" 处允许转换成功,那么在 "TWO" 处,我们会将一个 String 赋值给类型为 Integer[] 的变量。

这是不能被允许的。这个转换必须失败。


你问题的第二部分是:

如何在给定数字 k 的情况下创建一个 k 维数组?

这取决于你的意思:

  • 你可以创建一个自定义类,像 K 维数组一样运作,尽管你将无法使用 Java 数组语法来访问和更新单元格。

  • 你可以使用 Object[] 对象构建一个 K 维数组,尽管你需要进行大量的类型转换才能使用它。在任何情况下,你都无法将其转换为具有更多维度的数组。

  • 你可以使用 java.lang.reflect.Array.newInstance(Class, int...) 来创建具有 K 维的数组。唯一的问题是声明的类型是 Object,因此你仍然需要进行类型转换:

Integer[][][] array = Array.newInstance(Integer.class, 3, 3, 3);

然而,如果你想要将 K 作为参数传递,那么可以这样:

int[] dimensions = new int[K];
for (int i = 0; i < K; i++) {
    dimensions[i] = 2;
}
Object array = Array.newInstance(Integer.class, dimensions);

问题在于当 K 是一个参数时,你无法声明一个 Java 类型为 K 维 Integer 数组的变量。如果你想要使用 [] 进行下标访问,你需要类似这样的处理:

switch (K) {
case 1:
    Integer[] oneD = (Integer[]) array;
    oneD[1] = 42;
    break;
case 2:
    Integer[][] twoD = (Integer[][]) array;
    twoD[1][1] = 42;
    break;
// 等等
}
英文:

The type Object[][] is saying that the array can only contain other Object[] instances.

But an Object[] can also contain things that are not arrays of Object.

Note that when you cast from one reference type to another, no value conversion occurs, and the actual type of the object doesn't change. All that happens is that the runtime system checks that the object's actual runtime type is assignment compatible with the type you are casting to.


To illustrate why it has to be like this, consider the following:

     Object[] s = new Object[2];
     s[0] = new Integer[1];
     Integer[][] t = (Integer[][]) s;   // ONE
     s[1] = &quot;Hello&quot;;
     Integer[] u = t[1];                // TWO

If (hypothetically!) the cast at "ONE" is allowed to succeed, then at "TWO" we would assign a String to a variable of type Integer[].

That cannot be allowed to happen. The cast must fail.


The second part of your question is this:

> And how can I achieve that giving a number k, and create a array that is k dimensional.

It depends on what you mean:

  • You can create a custom class that behaves like a K-dimensional array, though you won't be able use Java array syntax to access and update cells.

  • You can construct a K-dimensional array out of Object[] objects, though you will need to do a lot of type-casting to use it. And under no circumstances will you be able to cast it to an array with a higher number of dimensions.

  • You can use java.lang.reflect.Array.newInstance(Class, int...) to create an array with K dimensions. The only problem that the declared type is Object so you still need a type cast:

     Integer[][][] array = Array.newInstance(Integer.class, 3, 3, 3);
    

    However, if you want K to be a parameter, then

     int[] dimensions = new int[K];
     for (int i = 0; i &lt; K; i++) {
         dimensions[i] = 2;
     }
     Object array = Array.newInstance(Integer.class, dimensions);
    

    The problem is that when K is a parameter, you cannot declare a variable whose Java type is a K-dimensional array of Integer. If you want to subscript the array using [], you will need to resort to something like this:

     switch (K) {
     case 1:
        Integer[] oneD = (Integer[]) array;
        oneD[1] = 42;
        break;
     case 2:
        Integer[][] twoD = (Integer[][]) array;
        twoD[1][1] = 42;
        break;
     // etcetera
     }
    

答案2

得分: 0

为了回答这一部分

> 而且我该如何实现

您可以进行以下转换

Integer[][] t = Arrays.stream((Object[])m).map(Integer[].class::cast).toArray(Integer[][]::new);
英文:

To answer the part

> And how can I achieve that

You can do the below transform

Integer[][] t = Arrays.stream((Object[])m).map(Integer[].class::cast).toArray(Integer[][]::new);

huangapple
  • 本文由 发表于 2020年7月23日 15:30:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/63049048.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定