我有这个:
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
我不希望我的第二个对象改变第一个对象中的值。 有没有办法阻止这种情况发生,但仍然可以从另一个对象复制属性?
答案 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());
}
但请注意,两个列表现在都包含相同的对象。同样,这只会创建一个新列表并复制原始列表中对象的引用值。如果您需要两个包含唯一对象的完整且单独的列表,则需要编写执行深层复制的方法,同时复制列表中的对象。