java cloneable_Java中的深克隆和浅克隆——Cloneable接口

一、没有使用克隆带来的问题

public class CloneTest

{

static Student s = new Student("aaa", 20);

// 直接赋值带来的问题

public static void noclone()

{

// 传的是引用的副本,改变了noCloneStudent也改变了s

Student noCloneStudent = new Student();

noCloneStudent = s;

noCloneStudent.setName("bbb");

noCloneStudent.setAge(21);

System.out.println(s);

System.out.print(noCloneStudent);

}

}

Student [name=bbb, age=21]

Student [name=bbb, age=21]

本意是设置noCloneStudent中的值,但把原来的对象s中的值也改变了。

二、浅克隆与深克隆

①浅克隆——若要克隆Student对象,只克隆他自身以及他包含的所有对象的引用地址。

②深克隆——克隆除自身以外所有的对象,包括自身所包含的所有对象实例。由具体的需求决定深克隆的层次(N层克隆)。

三、浅克隆

public class Student implements Cloneable

{

private String name;

private int age;

public Student()

{

super();

}

public Student(String name, int age)

{

super();

this.name = name;

this.age = age;

}

// 浅克隆

protected Object clone() throws CloneNotSupportedException

{

return super.clone();

}

public String toString()

{

return "Student [name=" + name + ", age=" + age + "]";

}

......

}

public class CloneTest

{

static Student s = new Student("aaa", 20);

// 浅克隆

public static void test0() throws Exception

{

Student ss = (Student) s.clone();

ss.setName("bbb");

ss.setAge(21);

System.out.println(s);

System.out.print(ss);

}

}

Student [name=aaa, age=20]

Student [name=bbb, age=21]

克隆的效果就达到了。

四、深克隆

public class TClass implements Cloneable

{

private Student stu;

private String name;

private List courses = new ArrayList();

public TClass()

{

super();

}

public TClass(Student stu, String name, List courses)

{

super();

this.stu = stu;

this.name = name;

this.courses = courses;

}

// 深克隆

public Object clone() throws CloneNotSupportedException

{

TClass tea = (TClass) super.clone();

tea.stu = (Student) tea.stu.clone();

return tea;

}

public String toString()

{

return "TClass [stu=" + stu + ", name=" + name + ", courses=" + courses + "]";

}

......

}

// 深克隆

public static void test1() throws Exception

{

TClass t = new TClass();

t.setStu(s);

t.setName("张老师");

t.getCourses().add("JAVA");

t.getCourses().add("C#");

System.out.println(t);

TClass tt = (TClass) t.clone();

Student sss = (Student) s.clone();

sss.setName("bbb");

sss.setAge(21);

tt.setStu(sss);

tt.setName("李老师");

tt.getCourses().add("oracle");

tt.getCourses().add("mysql");

System.out.println(t);

System.out.println(tt);

}

TClass [stu=Student [name=aaa, age=20], name=张老师, courses=[JAVA, C#]]

TClass [stu=Student [name=aaa, age=20], name=张老师, courses=[JAVA, C#, oracle, mysql]]

TClass [stu=Student [name=bbb, age=21], name=李老师, courses=[JAVA, C#, oracle, mysql]]

动态数组还是保留了原来的引用,所以其数组没有达到拷贝的效果。

改造一下,让其中的数组有新的引用

public class TClass implements Cloneable

{

private Student stu;

private String name;

private List courses = new ArrayList();

public TClass()

{

super();

}

public TClass(Student stu, String name, List courses)

{

super();

this.stu = stu;

this.name = name;

this.courses = courses;

}

// 深克隆(更深一层)

public Object clone() throws CloneNotSupportedException

{

TClass tea = (TClass) super.clone();

tea.stu = (Student) tea.stu.clone();

tea.courses = new ArrayList(); // 指向不同引用

return tea;

}

public String toString()

{

return "TClass [stu=" + stu + ", name=" + name + ", courses=" + courses + "]";

}

......

}

TClass[stu=Student [name=aaa, age=20], name=张老师, courses=[Java, C#]]

TClass[stu=Student [name=bbb, age=21], name=李老师, courses=[oracle, mysql]]

再改造一下,希望动态数组既有了新的引用,又保留了原值

public class TClass3 implements Cloneable

{

private Student stu;

private String name;

private List courses = new ArrayList();

public TClass()

{

super();

}

public TClass(Student stu, String name, List courses)

{

super();

this.stu = stu;

this.name = name;

this.courses = courses;

}

// 深克隆(更深一层)

public Object clone() throws CloneNotSupportedException

{

TClass tea = (TClass) super.clone();

tea.stu = (Student) tea.stu.clone();

// 指向不同引用

tea.courses = new ArrayList();

// 又想保留原有的值

for (int i = 0; i < courses.size(); i++)

{

tea.courses.add(courses.get(i));

}

return tea;

}

public String toString()

{

return "TClass [stu=" + stu + ", name=" + name + ", courses=" + courses + "]";

}

......

}

Teacher [stu=Student [name=aaa, age=20], name=张老师, courses=[Java, C#]]

Teacher [stu=Student [name=bbb, age=21], name=李老师, courses=[Java, C#, oracle, spring]]

原文:http://woshixy.blog.51cto.com/5637578/1409503

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值