Java中的深浅拷贝属于对象拷贝。即将一个对象的所有属性拷贝到另一个有着相同类类型的对象中去。这两种拷贝虽然相似但是仍然存在着不同,下文会分别介绍深拷贝和浅拷贝。
浅拷贝
若拷贝的数据类型是基本数据类型,则浅拷贝会创建新的对象并进行值传递;若拷贝的数据类型非基本数据类型,则浅拷贝会创建新的对象进行引用传递:将原来对象属性的地址复制在新对象中。对于第一种基本数据类型浅拷贝使用的是值传递,因此在更改原来对象的属性时,新对象的属性是不会受到影响的。而当拷贝的数据为非数据类型时,两个对象属性的地址是相同的,因此在改变其中任意一个对象时,另一个也会受到影响。
下面使用拷贝构造方法:
public class ShallowCopy
{
public static void main(String[] args)
{
Price a = new Price(200000);
Car c1 = new Car(a,"AAA");
Car c2 = new Car(c1);
System.out.println("c1是" + c1);
System.out.println("c2是" + c2);
c1.setName("BBB");
a.setPrice(100000);
System.out.println("修改后的c1是" + c1);
System.out.println("修改后的c2是" + c2);
}
}
class Car
{
private Price price;
private String name;
public Car(Price price,String name)
{
this.price = price;
this.name = name;
}
public Car(Car c)
{
this.name = c.name;
this.price = c.price;
}
public void setName(String name)
{
this.name = name;
}
public String toString()
{
return this.name+" " + this.price;
}
}
class Price
{
private int price;
public Price(int price)
{
this.price = price;
}
public void setPrice(int price)
{
this.price = price;
}
public int getPrice()
{
return this.price;
}
public String toString()
{
return getPrice() + "";
}
}
可见在传递字符串类型的时候改变原来的c1并不会改变c2,而传递Price类型的时候是引用传递,因此会对c2进行改变。
深拷贝
深拷贝对引用数据类型的成员变量中所有的对象都开辟了内存空间,因此源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。
通过重写clone代码来实现:
public class DeepCopy
{
public static void main(String[] args)
{
Age a=new Age(20);
Student stu1=new Student("AAA",a,180);
Student stu2=(Student)stu1.clone();
System.out.println(stu1.toString());
System.out.println(stu2.toString());
stu1.setName("BBB");
a.setAge(18);
stu1.setLength(174);
System.out.println(stu1.toString());
System.out.println(stu2.toString());
}
}
class Age implements Cloneable
{
private int age;
public Age(int age)
{
this.age=age;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String toString()
{
return this.age+"";
}
public Object clone()
{
Object obj=null;
try
{
obj=super.clone();
} catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
return obj;
}
}
class Student implements Cloneable
{
private String name;
private Age aage;
private int length;
public Student(String name,Age a,int length)
{
this.name=name;
this.aage=a;
this.length=length;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Age getaAge()
{
return this.aage;
}
public void setaAge(Age age)
{
this.aage=age;
}
public int getLength()
{
return this.length;
}
public void setLength(int length)
{
this.length=length;
}
public String toString()
{
return "姓名是: "+this.getName()+", 年龄为: "+this.getaAge().toString()+", 身高是: "+this.getLength();
}
public Object clone()
{
Object obj=null;
try {
obj= super.clone();
} catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
Student stu=(Student)obj;
stu.aage=(Age)stu.getaAge().clone();
return obj;
}
}
经过调试发现改变任意对象的属性都不会影响另外一个对象的属性。