一、介绍
java中没有指针概念,所以存在对象的引用问题。如果对象作为参数传递或者直接使用=其实都是对对象的引用。也就是你修改第二个对象的同时第一个对象的内容也改变了。二者地址相同。所以java中需要通过继承Cloneable接口实现对象的克隆。
浅克隆是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。
深克隆不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。
彻底理解Java深克隆和浅克隆的原理及实现
浅复制图:可以看见复制的list中只是重新复制了一份引用地址。但是引用对象没变。如果我们修改引用对象那么就会对两个list都会造成影响,但是如果只是删除,对另一个就没有影响。
二、浅Clone
浅克隆又称影子克隆。一般情况下适用于java基本数据类型和string类型。对于复杂类型无法满足要求。
package test;
public class CloneTest implements Cloneable {
public String name;
public Object clone() {
Object clone = null;
try{
clone = super.clone();
} catch (CloneNotSupportedException e){
e.printStackTrace();
}
return clone;
}
public static void main(String[] args){
CloneTest test = new CloneTest();
CloneTest copyTest = new CloneTest();
test.name = "AAAA";
copyTest = (CloneTest)test.clone();
copyTest.name = "BBBB";
System.out.println(test.name);
System.out.println(copyTest.name);
}
}
三、深Clone
对于复杂成员,vector、数组之类的需要采用深层克隆。
package test;
public class CloneTest implements Cloneable {
public String[] name = new String[2];
public Object clone() {
CloneTest clone = null; //注意申明的对象,后面调用clone.name需要类中有此类型
try{
clone = (CloneTest)super.clone();
clone.name = (String[])name.clone();
} catch (CloneNotSupportedException e){
e.printStackTrace();
}
return clone;
}
public static void main(String[] args){
CloneTest test = new CloneTest();
CloneTest copyTest = new CloneTest();
test.name[0] = "AAAA";
test.name[1] = "AA11";
copyTest = (CloneTest)test.clone();
copyTest.name[0] = "BBBB";
copyTest.name[1] = "BB11";
System.out.println(test.name[0]);
System.out.println(copyTest.name[0]);
}
}