0

我了解到,对于数组,该clone方法表现良好,我们可以使用它。但我认为数组持有的元素的类型应该已经实现了Cloneable接口。让我举个例子:

public class test {

    public static void main(String[] args){
        Test[] arr_t = new Test[1];
        arr_t[0] = new Test(10);
        Test[] an_arr = arr_t.clone(); 
        an_arr[0]= new Test(5);
        System.out.println(an_arr[0].test); //5
        System.out.println(arr_t[0].test);  //10
    }

    public static class Test{
        public int test;
        public Test(int test) {
            this.test = test;
        }
    }
}

演示

我认为 5 应该打印两次。这样做的原因是通过克隆数组,我们正在创建新数组,其中包含对第一个数组持有的对象的引用(因为元素的类型没有实现Cloneable)。你不能把事情弄清楚吗?

目前尚不清楚数组元素的类型是否需要实现Cloneable

4

4 回答 4

2

这是一个简单的概念,但似乎很难解释。克隆数组时,内存中有两个分区数组,但它们的索引值相同。


在您的第二个数组中an_arran_array[0] = new Test(5)您将在插槽 0 中放置另一个引用。

但是克隆的索引 0 与克隆的数组位于不同的位置。

如果你这样做,你的例子是有效的

Test[] arr_t = new Test[1];
arr_t[0] = new Test(10);
Test[] an_arr = arr_t.clone(); 
an_arr[0].test = 5; // look here, I changed the object
System.out.println(an_arr[0].test); //5
System.out.println(arr_t[0].test);  //5

现在两者都将打印相同的值,因为它们对同一个对象持有相同的引用,但是该引用的存储位置不同。

于 2015-06-25T13:32:45.130 回答
0

.clone() 制作所谓的“浅拷贝”。这意味着它在运行该方法时尽可能少地复制;而不是复制数组的内容,它只是创建对原始数组内容的引用。

如果您通过调用更改引用:

new Test(5)

然后,您已经覆盖了该引用,并获得了新数据。

另一种方法是数组的深层副本。在较大的对象上执行这些操作可能会很昂贵,因此它们不是默认设置。

于 2015-06-25T13:39:18.550 回答
0

不管数组clone()的类型如何,数组都会做同样的事情:它创建一个相同类型和大小的新数组,然后将数组的每个元素分配 ( =) 给新数组的每个元素。而已。

因此,如果您有一个由 指向的 3 元素数组arrarr.clone()返回newArr,那么在创建新数组之后,它只需执行以下操作:

newArr[0] = arr[0];
newArr[1] = arr[1];
newArr[2] = arr[2];

而已。数组的类型不相关。元素中没有“克隆”或任何内容。它不知道(或关心)元素是否有某种克隆方法(事实上,Java 中没有用于克隆的通用 API,所以这是不可能的)。

(顺便说一句,即使它以某种方式将克隆的对象放入新数组中,您示例中的结果仍然是相同的,因为您正在为数组分配一个新值,所以之前的内容并不重要.)

所以你的问题基本上是为什么:

Test[] arr_t = new Test[1];
arr_t[0] = new Test(10);
Test[] an_arr = new Test[1];
an_arr[0] = arr_t[0]; 
an_arr[0] = new Test(5);
System.out.println(an_arr[0].test); //5
System.out.println(arr_t[0].test);  //10

你可以从那里弄清楚。

于 2015-06-26T00:33:31.443 回答
0

这里的“问题”是数组包含对对象的引用,而不是对象。此外,这与克隆无关。

当你执行:

an_arr[0] = new Test(5);

您正在将新对象的引用分配给第一个元素。

此外,每个数组都有自己对 Test 对象的引用。克隆数组时,仅复制引用(而不是它们引用的对象)。

于 2015-06-26T04:21:49.030 回答