先看一个普通的赋值代码:
public class copyTest {
private String name;
private int age;
public copyTest(String name, int age) {
this.name = name;
this.age = age;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void display() {
System.out.println("Name:" + name + ",Age:" + age);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
copyTest ct1 = new copyTest("张三",24);
copyTest ct2 = ct1;
ct2.setAge(20);
ct1.setName("李四");
ct1.display();
ct2.display();
}
}
这段代码最后输出的结果为:
Name:李四,Age:20
Name:李四,Age:20
根据结果我们可以知道,ct1和ct2指的其实都是一个对象,任意一方对对象的修改都会影响到另一方,他们对象的属性是共享的。
我们来看什么是浅拷贝:
浅拷贝(Shallow Copy):①对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。因为是两份不同的数据,所以对其中一个对象的该成员变量值进行修改,不会影响另一个对象拷贝得到的数据。②对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值。
public class ShallowCopyTest implements Cloneable{
private String name;
copyTest ct ;
public ShallowCopyTest(String name, copyTest ct) {
this.name = name;
this.ct = ct;
}
public void setName(String name) {
this.name = name;
}
public Object clone(){
ShallowCopyTest b = null;
try{
b = (ShallowCopyTest)super.clone();
}catch(Exception e){
e.printStackTrace();
}
return b;
}
public void display() {
System.out.println("Name:" + name);
ct.display();
}
public static void main(String[] args) {
ShallowCopyTest sct1 = new ShallowCopyTest("sssss",new copyTest("张三",22));
ShallowCopyTest sct2 = (ShallowCopyTest)sct1.clone();
sct2.name = "aaaaa";
sct1.ct.setAge(33);
sct2.ct.setName("李四");
sct1.display();
sct2.display();
}
}
结果:
Name:sssss
Name:李四,Age:33
Name:aaaaa
Name:李四,Age:33
再浅拷贝中,对象的基本数据类型的值被直接拷贝,引用数据类型的引用被拷贝,所以对引用的修改作用的还是同一个对象。
我们再来看什么是深拷贝:
深拷贝:设想一下,一个类有一个对象,其成员变量中又有一个对象,该对象指向另一个对象,另一个对象又指向另一个对象,直到一个确定的实例。这就形成了对象图。那么,对于深拷贝来说,不仅要复制对象的所有基本数据类型的成员变量值,还要为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。也就是说,对象进行深拷贝要对整个对象图进行拷贝!
简单地说,深拷贝对引用数据类型的成员变量的对象图中所有的对象都开辟了内存空间;而浅拷贝只是传递地址指向,新的对象并没有对引用数据类型创建内存空间。
//copyTest继承Cloneable重写clone方法
public Object clone(){
copyTest st = null;
try{
st = (copyTest)super.clone();
}catch(Exception e){
e.printStackTrace();
}
return st;
}
//ShallowCopyTest改良clone方法
public Object clone(){
ShallowCopyTest sct = null;
try{
sct = (ShallowCopyTest)super.clone();
}catch(Exception e){
e.printStackTrace();
}
sct.ct = (copyTest)ct.clone();
return sct;
}
修改都的运行结果为:
Name:sssss
Name:张三,Age:33
Name:aaaaa
Name:李四,Age:22
进行了深拷贝之后,无论是什么类型的属性值的修改,都不会影响另一个对象的属性值。