复制内存中的整个对象

时间:2012-07-26 19:35:09

标签: java

我有这个:

import java.util.ArrayList;


public class MyClass {
    ArrayList list = new ArrayList();

    public MyClass(){

    }

    public MyClass(MyClass aClass){
        this.list = aClass.getList();
    }

    public void add(int number){
        list.add(number);
    }

    public void set(int number){
        list.set(0, number);
    }

    public int get(){
        return (Integer)list.get(0);
    }

    public ArrayList getList(){
        return list;
    }
}



MyClass aName = new MyClass();
aName.add(5);
System.out.println("aName: "+aName.get());

MyClass aName2 = new MyClass(aName);
System.out.println("aName2: "+aName2.get());

aName2.set(1);
System.out.println("aName2: "+aName2.get());
System.out.println("aName: "+aName.get());

这将打印: aName:5 aName2:5 aName2:1 aName:1

我不希望我的第二个对象改变第一个对象中的值。 有没有办法阻止这种情况发生,但仍然可以从另一个对象复制属性?

4 个答案:

答案 0 :(得分:1)

然后不要将List从原始对象传递到

中的新对象
public MyClass(MyClass aClass){ 
    this.list = aClass.getList(); 
} 

它使两个对象都引用同一个列表(两个对象之间只共享一个列表)。

你应该做

public MyClass(MyClass aClass){ 
    this.list = (List) aClass.getList().clone(); 
} 

答案 1 :(得分:1)

是的,你可以阻止这一点。您需要在复制构造函数中对列表进行防御性复制

public MyClass(MyClass aClass){
    this.list = new ArrayList(aClass.getList());
}

你可以使用clone(),但正如Josh Bloch在Effective Java项目中所说的那样“复制构造函数比clone有许多优点” - 它们在实践中更受欢迎。

答案 2 :(得分:1)

您可以克隆()或复制,但由于您已经创建了一个列表,而不是丢弃它,您可以使用它。 ;)

public MyClass(MyClass aClass){
    this.list.addAll(aClass.getList());
}

答案 3 :(得分:0)

您正在将ArrayList参考值复制到新对象中。您现在有两个对同一列表的引用。

构建第二个对象时需要创建一个新的ArrayList

public MyClass(MyClass aClass){
    this.list = new ArrayList(aClass.getList());
}

但请注意,两个列表现在都包含相同的对象。同样,这只会创建一个新列表并复制原始列表中对象的引用值。如果您需要两个包含唯一对象的完整且单独的列表,则需要编写执行深层复制的方法,同时复制列表中的对象。