我在java中面临对象克隆的问题.
public class TestClass {
private int count;
private List<Integer> list;
public final int getCount() {
return count;
}
public final void setCount(int count) {
this.count = count;
}
public final List<Integer> getList() {
return list;
}
public final void setList(List<Integer> list) {
this.list = list;
}
}
public class Main {
public static void main(String[] args) {
TestClass obj = new TestClass();
obj.setCount(5);
List<Integer> temp = new ArrayList<Integer>();
temp.add(1);
temp.add(2);
obj.setList(temp);
TestClass newObj= obj;
System.out.println(newObj.getList().size());
obj.getList().add(3);
System.out.println(newObj.getList().size());
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是2,3.但我想要的输出是2,2但是因为java将"obj"的引用分配给newObj.反正有没有避免这个?我已经看到序列化对象并反序列化它将给"newObj"提供全新的引用.但还有其他有效的方法吗?
首先,你实际上并没有克隆在java中意味着你使用该object.clone()
方法.clone 生成一个对象的浅表副本.您刚刚对同一个对象进行了第二次引用.
在你的代码中,调用
obj.getList().add(3);
Run Code Online (Sandbox Code Playgroud)
是相同的
newObj.getList().add(3);
Run Code Online (Sandbox Code Playgroud)
这就是它打印的原因.
您需要制作对象的深层副本,这样不仅实例TestClass
不同,而且所有字段也不同.
最简单的方法是制作复制方法和/或复制构造函数
public class TestClass{
public TestClass(){
}
//copy constructor
public TestClass( TestClass copy){
this.list = new ArrayList<Integer>(copy.list);
this.count = copy.count;
}
...
}
Run Code Online (Sandbox Code Playgroud)
然后使用它:
TestClass newObj= new TestClass(obj);
Run Code Online (Sandbox Code Playgroud)