淺克隆和深克隆

淺複製和深複製:java

錢復制:克隆對象(A1)的全部變量都含有與原對象(A)相同的值,對象內部的引用對象(B)仍然指向原來的對象(B),淺複製僅僅複製所考慮的對象,而不復制它所引用的對象this

深複製:克隆對象(A1)的全部變量都含有與原對象(A)相同的值,除去那些引用對象(B),那些引用對象(B)的變量將指向被複制過的新對象B1,而再也不是原有的那些被引用的對象(B),深複製把要複製對象spa

所引用的對象都複製一遍對象

Java中的clone方法接口

(1)clone方法將對象複製一份並返回給被調用者,clone方法知足:get

1.對任何的對象x,都有x.clone!=x  即克隆對象與原對象不是同一個對象it

2.對任何的對象x,都有x.clone.getClass == x.getClass  克隆對象與原對象類型同樣io

3.若是對象x的equals方法定義恰當,那麼x.clone.equals(x)應該成立class


(2)java中對象的克隆import

1.位了獲取對象的一份拷貝,咱們能夠利用Object的clone方法

2.在派生子類中定義克隆方法,名字隨意,能夠叫clone(),並聲明爲public

3.在派生類的克隆方法中,調用super.clone()

4.派生類實現cloneable接口

1. 淺複製案例:

public class Professer{

String name;

int age;

public Professer(String name,int age) {

this.name = name;

this.age = age;

}

}

public class Student implements Cloneable{

String name;

int age;

Professer p;

Student(String name,int age,Professer p){

this.name = name;

this.age = age;

this.p = p;

}

public Student clone2() throws CloneNotSupportedException{

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

/********/

//若是professer類不實現cloneable接口,並且不寫克隆方法供下面調用(s.p = p.clone3()方法被註釋掉),則生成的結果如p1.png

//說明:1.克隆對象與原對象中的變量值是同樣的,引用對象指向的是同一個對象;2.修改克隆對象中的普通變量對原對象沒有影響,但修改克隆對象中引用對象的值,原對象中引用對象的值也發生改變

//********上述這種複製方式爲淺複製*******//

//若是professer類實現了cloneable接口,並且寫了克隆方法供下面調用(s.p = p.clone3()存在),則生成結果如p2.png

//說明:1.克隆對象與原對象中的變量值是同樣的,引用對象指向的不是同一個對象;2.修改克隆對象中的普通變量對原對象沒有影響,同時修改克隆對象引用對象的值,原對象中引用對象的值沒變,克隆對象

//中的引用對象和元對象中的引用對象不是一個東西

//********上述這種複製方式爲深複製******//

//s.p =  p.clone3();

/*********/

return s;

}

public static void main(String[] args) throws CloneNotSupportedException {

Professer p3 = new Professer("王五", 50);

Student s1 = new Student("張三", 18, p3);

Student s2 = s1.clone2();

System.out.println("[v1]s1.name = " + s1.name + ";s1.age = " + s1.age + ";s1.p.name = " + s1.p.name + ";s1.p.age = " + s1.p.age);

System.out.println("[v1]s2.name = " + s2.name + ";s2.age = " + s2.age + ";s2.p.name = " + s2.p.name + ";s2.p.age = " + s2.p.age);

System.out.println();

s2.name = "李四";

s2.age = 20;

System.out.println("[v2]s1.name = " + s1.name + ";s1.age = " + s1.age + ";s1.p.name = " + s1.p.name + ";s1.p.age = " + s1.p.age);

System.out.println("[v2]s2.name = " + s2.name + ";s2.age = " + s2.age + ";s2.p.name = " + s2.p.name + ";s2.p.age = " + s2.p.age);

System.out.println();

s2.p.name = "趙六";

s2.p.age = 100;

System.out.println("[v3]s1.name = " + s1.name + ";s1.age = " + s1.age + ";s1.p.name = " + s1.p.name + ";s1.p.age = " + s1.p.age);

System.out.println("[v3]s2.name = " + s2.name + ";s2.age = " + s2.age + ";s2.p.name = " + s2.p.name + ";s2.p.age = " + s2.p.age);

}

}

總結:

(1).淺克隆中,克隆對象中普通變量和引用對象的值,都與原對象的值保持一致;

(2).淺克隆時,克隆對象和原對象不是同一個對象,但他們內部的【引用對象】指向的是同一個對象

(3).淺克隆時,修改普通變量,克隆對象和原對象互不影響,但修改引用對象時,二者引用對象的值同時改變


深克隆:

原對象A;

引用對象B;

克隆對象A1;

深複製的兩種方式:

1. B實現cloneable接口,提供克隆方法,A實現cloneable接口,提供克隆方法的同時,調用B的克隆方法

2. 利用串行化來作深複製P:在Java裏,深複製一個對象,經常能夠先使對象實現serializabel接口,而後把對象寫到一個流裏,再從流裏讀出來,即可以重建對象;

=====>前提是要保證對象和對象內部全部引用到的對象都是可串行化的

案例1:

public class Professer implements Cloneable{

String name;

int age;

public Professer(String name,int age) {

this.name = name;

this.age = age;

}

public Professer clone3() throws CloneNotSupportedException{

return (Professer) super.clone();

}

}

public class Student implements Cloneable{

String name;

int age;

Professer p;

Student(String name,int age,Professer p){

this.name = name;

this.age = age;

this.p = p;

}

public Student clone2() throws CloneNotSupportedException{

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

/********/

//若是professer類不實現cloneable接口,並且不寫克隆方法供下面調用(s.p = p.clone3()方法被註釋掉),則生成的結果如p1.png

//說明:1.克隆對象與原對象中的變量值是同樣的,引用對象指向的是同一個對象;2.修改克隆對象中的普通變量對原對象沒有影響,但修改克隆對象中引用對象的值,原對象中引用對象的值也發生改變

//********上述這種複製方式爲淺複製*******//

//若是professer類實現了cloneable接口,並且寫了克隆方法供下面調用(s.p = p.clone3()存在),則生成結果如p2.png

//說明:1.克隆對象與原對象中的變量值是同樣的,引用對象指向的不是同一個對象;2.修改克隆對象中的普通變量對原對象沒有影響,同時修改克隆對象引用對象的值,原對象中引用對象的值沒變,克隆對象

//中的引用對象和元對象中的引用對象不是一個東西

//********上述這種複製方式爲深複製******//

s.p =  p.clone3();

/*********/

return s;

}

public static void main(String[] args) throws CloneNotSupportedException {

Professer p3 = new Professer("王五", 50);

Student s1 = new Student("張三", 18, p3);

Student s2 = s1.clone2();

System.out.println("[v1]s1.name = " + s1.name + ";s1.age = " + s1.age + ";s1.p.name = " + s1.p.name + ";s1.p.age = " + s1.p.age);

System.out.println("[v1]s2.name = " + s2.name + ";s2.age = " + s2.age + ";s2.p.name = " + s2.p.name + ";s2.p.age = " + s2.p.age);

System.out.println();

s2.name = "李四";

s2.age = 20;

System.out.println("[v2]s1.name = " + s1.name + ";s1.age = " + s1.age + ";s1.p.name = " + s1.p.name + ";s1.p.age = " + s1.p.age);

System.out.println("[v2]s2.name = " + s2.name + ";s2.age = " + s2.age + ";s2.p.name = " + s2.p.name + ";s2.p.age = " + s2.p.age);

System.out.println();

s2.p.name = "趙六";

s2.p.age = 100;

System.out.println("[v3]s1.name = " + s1.name + ";s1.age = " + s1.age + ";s1.p.name = " + s1.p.name + ";s1.p.age = " + s1.p.age);

System.out.println("[v3]s2.name = " + s2.name + ";s2.age = " + s2.age + ";s2.p.name = " + s2.p.name + ";s2.p.age = " + s2.p.age);

}

}

案例2:

import java.io.Serializable;

public class Teacher implements Serializable{

private static final long serialVersionUID = 1L;

String name;

int age;

Teacher(String name,int age){

this.name = name;

this.age = age;

}

}

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.io.Serializable;


public class Student implements Serializable{

private static final long serialVersionUID = 1L;

String name;

int age;

Teacher t;

public Student(String name,int age,Teacher t){

this.name = name;

this.age = age;

this.t = t;

}

public Student deetClone() throws IOException, ClassNotFoundException{

ByteArrayOutputStream bos = new ByteArrayOutputStream();

ObjectOutputStream oos = new ObjectOutputStream(bos);

oos.writeObject(this);

ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());

ObjectInputStream ois = new ObjectInputStream(bis);

return (Student) ois.readObject();

}

public static void main(String[] args) throws ClassNotFoundException, IOException {

Teacher t = new Teacher("AAA",30);

Student s1 = new Student("A", 10, t);

Student s2 = s1.deetClone();

System.out.println("[v1]s1.name = " + s1.name + ";s1.age = " + s1.age + "; s1.t.name = " + s1.t.name + ";s1.t.age = " + s1.t.age);

System.out.println("[v1]s2.name = " + s2.name + ";s2.age = " + s2.age + "; s2.t.name = " + s2.t.name + ";s2.t.age = " + s2.t.age);

System.out.println();

s2.t.name = "BBB";

s2.t.age = 50;

System.out.println("[v1]s1.name = " + s1.name + ";s1.age = " + s1.age + "; s1.t.name = " + s1.t.name + ";s1.t.age = " + s1.t.age);

System.out.println("[v1]s2.name = " + s2.name + ";s2.age = " + s2.age + "; s2.t.name = " + s2.t.name + ";s2.t.age = " + s2.t.age);

}

}

相關文章
相關標籤/搜索