【问题标题】:Java - array types to Object type castJava - 数组类型到对象类型转换
【发布时间】:2015-06-22 16:49:12
【问题描述】:

java 如何将数组类型转换为对象类型? 例如,假设我们有一个 int 数组 'src' 并且我们使用 System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 那么 java 如何将原始类型数组转换为 Object 的实例?同样在复制到'dest'时,它如何知道如何在不知道类型的情况下复制它?

它只是像克隆一样逐字节复制吗,因为当我运行以下代码时

int[][] a = new int[][] {{1,2,3,4,5},{6,7,8,9,0}};
int[][] b = new int[a.length][a[0].length];
System.arraycopy(a,0,b,0,a.length);
System.out.println(java.util.Arrays.toString(a));
b[1][3]=100;
System.out.println(java.util.Arrays.toString(a[0]));
System.out.println(java.util.Arrays.toString(a[1]));

我得到以下输出

[[I@7d08c1b7, [I@49e61582]
[1, 2, 3, 4, 5]
[6, 7, 8, 100, 0]

[[I@7d08c1b7, [I@49e61582] 的输出是什么?是不是像数组 a[0] 和 a[1] 的地址(像 C/C++ 中的指针数组)?

如果我更改了 b[1][3],a[1][3] 会如何变化?复制 a 的正确方法是什么?

编辑:java.lang.reflect.Array.getLength(Object array) 是如何工作的?

编辑:我想指出我更改了​​ b[1][3] 的值,但是在打印 a[1] 时,值 a[1][3] 也在发生变化。为什么会这样?

【问题讨论】:

    标签: java arrays types


    【解决方案1】:

    java如何将数组类型转换为Object类型?

    数组类型已经是Object的子类,所以不需要任何转换。

    java 如何将原始类型数组转换为 Object 的实例?同样在复制到'dest'时,它如何知道如何在不知道类型的情况下复制它?

    原始类型数组已经是 Object 的实例,因此不需要转换。 JVM 在运行时知道源数组和目标数组中存储的元素类型。如果它们不匹配,则抛出ArrayStoreException。

    如果我更改了 b[1][3],a[1][3] 会如何变化?复制 a 的正确方法是什么?

    System.arraycopy 不做深拷贝。它将源数组每个位置的图元或引用复制到目标数组。当源数组的元素本身是对子数组的引用时,该引用将按原样复制到目标数组。因此a[1] == b[1](它们引用同一个数组对象),所以更改b[1][3] 会更改a[1][3]。

    如果您希望每个子数组都是原始子数组的副本,则必须在对主数组执行System.arraycopy 之后,对每个子数组分别执行System.arraycopy。

    【讨论】:

      【解决方案2】:

      java如何将数组类型转换为Object类型?

      数组是一个容器对象,它包含固定数量的单一类型值。它存在于堆中。

      输出“[[I@7d08c1b7, [I@49e61582]”是什么?是不是像 数组 a[0] 和 a1 的地址(类似于 C/C++ 中的指针数组)?

      "[[I@7d08c1b7, [I@49e61582]" 是 a[0] 和 a1 的类名和哈希码

      如果我更改了 b1[3],a1[3] 会如何变化? 制作副本的正确方法?

      我写了一个示例代码

              int[] a = new int[]{1,2,3,4,5,6,7};
              int[] b = new int[a.length];
      
              b=Arrays.copyOf(a, a.length);
              //System.arraycopy(a, 0, b, 0, a.length);
              b[2]=789;
              System.out.println(Arrays.toString(a));
              System.out.println(Arrays.toString(b));
      

      输出

      [1, 2, 3, 4, 5, 6, 7]
      [1, 2, 789, 4, 5, 6, 7]
      

      b 的变化不会影响 a 的值。

      如果你想改变 b & 还想在 a 中进行后续改变

      只是做

      b=a;  //now b is a shallow copy of a
      

      复制数组对象的标准方法是使用Arrays.copyOf 方法。

      【讨论】:

      • 您的示例代码复制了一个一维数组,因此它的行为与问题中的二维数组不同。
      【解决方案3】:

      来自Object javadocs:

      Object 类的 toString 方法返回一个字符串,该字符串由 对象是其实例的类的名称,at 符号 字符“@”和哈希的无符号十六进制表示 对象的代码。换句话说,这个方法返回一个字符串等于 值:

       `getClass().getName() + '@' + Integer.toHexString(hashCode())`
      

      【讨论】:

        【解决方案4】:

        “[[I@7d08c1b7, [I@49e61582]”的输出是什么?是不是像 数组 a[0] 和 a[1] 的地址(类似于 C/C++ 中的指针数组)?

        是类名和hashCode。 getClass().getName() + '@' + Integer.toHexString(hashCode())

        如果我更改了 b[1][3],a[1][3] 会如何变化? 制作副本的正确方法?

        System.arraycopy 会创建一个新的数组,所以改成 b,对 b 没有影响。

        编辑:还有 java.lang.reflect.Array.getLength(Object array) 工作吗?

        如果 anArray 静态类型为数组类型,则应使用 anArray.length(不是方法调用)。如果您仅将数组引用为 Object,则可以使用反射形式。

        【讨论】:

        • System.arraycopy will create a new array, so what changed to b, there's no impact to b. 我假设你的意思是System.arraycopy will create a new array, so what changed to b, there's no impact to a.。这仍然是错误的,因为arraycopy执行的是浅拷贝,所以即使a!=b、a[i]==b[i]为真,改变b[i][j]也会改变a[i][j]。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-09
        • 1970-01-01
        • 1970-01-01
        • 2020-12-19
        • 1970-01-01
        相关资源
        最近更新 更多