今天看了下java下面的深浅复制问题,借鉴了网上资料自己整理一下。
Object中含有clone()方法,文章就在clone了里面了。
查看api,里面有此段描述:
按照惯例,clone()返回的对象应该独立于正被复制的对象。要获得此独立性,在super.clone 返回对象之前,有必要对该对象的一个或多个字段进行修改。这通常意味着要复制包含正在被复制对象的内部“深层结构”的所有可变对象(即对象中的对象),并使用对副本的引用替换对这些对象的引用。如果一个类只包含基本字段或对不变对象的引用,那么通常不需要重载clone()。
下面的代码注释完整,能够自我解释。
运行结果:
Object中含有clone()方法,文章就在clone了里面了。
查看api,里面有此段描述:
按照惯例,clone()返回的对象应该独立于正被复制的对象。要获得此独立性,在super.clone 返回对象之前,有必要对该对象的一个或多个字段进行修改。这通常意味着要复制包含正在被复制对象的内部“深层结构”的所有可变对象(即对象中的对象),并使用对副本的引用替换对这些对象的引用。如果一个类只包含基本字段或对不变对象的引用,那么通常不需要重载clone()。
下面的代码注释完整,能够自我解释。
//Cloneable必须实现
class StudentInfo implements Cloneable{
public long id;
public StudentInfo(long id) {
this.id = id;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Student{
public String name;
public int age;
public StudentInfo si;
Student(String name, int age, StudentInfo si) {
this.name = name;
this.age = age;
this.si = si;
}
@Override
protected Object clone() throws CloneNotSupportedException {
System.out.println("override clone");
StudentInfo studentInfo = (StudentInfo) this.si.clone();
return new Student(name, age, studentInfo);
}
}
class TestClone {
public static void main(String[] args) throws CloneNotSupportedException {
System.out.println("----------------基本类型的复制-----------");
// 基本类型,没有深浅复制,而且不能像c看到基本类型的地址
int a1 = 1;
int a2 = a1;
a2 = 2;
System.out.println(a1);
System.out.println(a2);
System.out.println("----------------对象的复制 1-----------");
// 对象深浅复制
// case 1: 当对象内部的变量都是基本类型
StudentInfo s1 = new StudentInfo(18);
StudentInfo s2 = (StudentInfo) s1.clone();
StudentInfo s3 = s1;
// 查看s[1...3]地址
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
// 修改学生信息2后,不影响
s2.id = 20;
System.out.println("id=" + s1.id );
System.out.println("id=" + s2.id );
// 修改学生信息3后,影响
s3.id = 22;
System.out.println("id=" + s1.id);
System.out.println("id=" + s3.id);
System.out.println("----------------对象的复制 2-----------");
// case 2: 对象内容变量含有对象
StudentInfo si = new StudentInfo(18);
Student ss1 = new Student("张三", 18, si);
// 进行深复制,需要重载clone方法
Student ss2 = (Student) ss1.clone();
Student ss3 = ss1;
System.out.println(ss1);
System.out.println(ss2);
System.out.println(ss3);
System.out.println(si + " " + ss2.si);
System.out.println(si!=ss2.si ? "深复制成功": "深复制失败");
}
}
运行结果: