天天看點

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]

本意是設定noclonestudent中的值,但把原來的對象s中的值也改變了。

二、淺克隆與深克隆

①淺克隆——若要克隆student對象,隻克隆他自身以及他包含的所有對象的引用位址。

②深克隆——克隆除自身以外所有的對象,包括自身所包含的所有對象執行個體。由具體的需求決定深克隆的層次(n層克隆)。

三、淺克隆

public class student implements cloneable

private string name;

private int age;

public student()

super();

public student(string name, int age)

this.name = name;

this.age = age;

// 淺克隆

protected object clone() throws clonenotsupportedexception

return super.clone();

public string tostring()

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

......

public static void test0() throws exception

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

ss.setname("bbb");

ss.setage(21);

system.out.print(ss);

student [name=aaa, age=20]

克隆的效果就達到了。

四、深克隆

public class tclass implements cloneable

private student stu;

private list<string> courses = new arraylist<string>();

public tclass()

public tclass(student stu, string name, list<string> courses)

this.stu = stu;

this.courses = courses;

// 深克隆

public object clone() throws clonenotsupportedexception

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

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

return tea;

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(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]]

動态數組還是保留了原來的引用,是以其數組沒有達到拷貝的效果。

改造一下,讓其中的數組有新的引用

// 深克隆(更深一層)

tea.courses = new arraylist<string>(); // 指向不同引用

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

// 指向不同引用

tea.courses = new arraylist<string>();

// 又想保留原有的值

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

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

teacher [stu=student [name=aaa, age=20], name=張老師, courses=[java, c#]]

teacher [stu=student [name=bbb, age=21], name=李老師, courses=[java, c#, oracle, spring]]