Java学习——33、浅拷贝和深拷贝
Java不提供默认拷贝构造方法,如果要将一个对象的值赋给另一个对象需要自己写拷贝构造方法。
1、拷贝构造方法
注:使用=并不是调用构造方法,而只是将地址赋给对象而已。
如:Person s=new Person();
Persons1=s;//意思是s1和s同时指向由上句new创建的实例。
此时,如果修改s的值,s1的值也会随之改变,如图所示:

但我们在修改s的值的时候,并不希望s1的值进行修改,故在创建对象时,如果是要复制已有对象的值,就需要用拷贝构造函数。
如上例,加上拷贝构造函数后:
public Person(Person p){//拷贝构造函数
this.name=p.name;
}
在main方法中,将Person s1=s改为person s1=new Person(s),再修改s的值,就不会影响s1的值了。

2、浅拷贝
当类中有引用成员类型,如对象成员时,比如Person类中有一MyDate类对象成员private Mydate birthday,此时在写拷贝构造方法时,若写成:
public Person(Person p,MyDate birthday){//拷贝构造函数
this.birthday=p.birthday;
this.name=p.name;
}
是不能实现对象值的拷贝的,而只是将p.birthday的地址赋给this.birthday。
故需要用深拷贝。
3、深拷贝
当一个类包含引用数据类型的成员变量时,该类的拷贝构造方法,不仅要复制对象的所有非引用成员变量值,还要为引用数据类型的成员变量创建新的实例,并初始化为形式参数实例值,即为深拷贝。
例:深拷贝见注释
package learn;
class MyDate{
private intyear,month,day;
public MyDate(){
year=2000;
month=1;
day=1;
}
public MyDate(int year,int month,int day){
this.year=year;
this.month=month;
this.day=day;
}
public MyDate(MyDate m){
this.year=m.year;
this.month=m.month;
this.day=m.day;
}
public void set(int year,int month,int day){
this.year=year;
this.month=month;
this.day=day;
}
public void show(){
System.out.println("\n生日:"+year+"年"+month+"月"+day+"日");
}
public void show1(){
System.out.println("welcome");
}
}
publicclassPersonTest
{
private String name;
public MyDate birthday;
public PersonTest(){
birthday=new MyDate();//此处赋值必须对引用成员变量新建实例,即为深拷贝
name="123";
}
public PersonTest(PersonTestp){//拷贝构造函数
this.birthday=new MyDate(p.birthday); //此处赋值必须对引用成员变量新建实例,即为深拷贝
this.name=p.name;
}
publicvoid display(){
System.out.println("姓名:"+name);
birthday.show();
}
publicstaticvoid main(String args[])
{
PersonTestp=newPersonTest();
p.display();
PersonTestp1=newPersonTest(p);
p1.display();
}
}
其运行结果如下:
