複製的對象的全部變量與含有與原來的對象相同的值,而全部的對其餘對象的引用仍然指向原對象。換言之,淺複製僅僅複製所考慮的對象,而不復制它所引用的對象。java
複製的對象的全部變量都含有與原來的對象相同的值,除去那些引用其餘對象的變量。那些引用其餘對象的變量將指向複製的新對象,而不是原來的對象。換言之,深複製把要複製的對象所引用的對象都複製了一遍。jvm
clone方法將對象複製了一份並返回給調用者。通常而言,clone()方法知足ide
package org.wem.im; /** * * <p> * Title: Person<br> * Copyright: Copyright (c) 2016<br> * Company: <br> * </p> * * <p> * Description: 測試Java對象淺克隆 * </p> * * @version v1.0.0 * @author kucs * @date 2016年9月30日下午2:28:22 * * Modification History: *---------------------------------------------------------* * */ public class Person implements Cloneable { class Worker{ private String workName; private String department; public String getWorkName() { return workName; } public void setWorkName(String workName) { this.workName = workName; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } @Override public String toString() { return "Worker [workName=" + workName + ", department=" + department + "]"; } } private String name; private String age; private String weight; private String height; private Worker worker; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getWeight() { return weight; } public void setWeight(String weight) { this.weight = weight; } public String getHeight() { return height; } public void setHeight(String height) { this.height = height; } public Worker getWorker() { return worker; } public void setWorker(Worker worker) { this.worker = worker; } @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", weight=" + weight + ", height=" + height + ", worker=" + worker + "]"; } public static void main(String[] args) throws CloneNotSupportedException { Person p = new Person(); Worker worker = p.new Worker(); worker.setWorkName("asiainfo"); worker.setDepartment("cboss"); p.setWorker(worker); p.setName("kucs"); p.setAge("24"); p.setWeight("65"); p.setHeight("170"); Person p_clone = (Person) p.clone(); System.out.println("原對象信息:"+p.toString()); System.out.println("克隆對象信息:"+p_clone.toString()); //修改p_clone對象的值 p_clone.setName("kucs_clone"); //修改對象引用的對象的值 worker.setWorkName("asianinfo_clone"); System.out.println("修改後的克隆對象信息:"+p_clone.toString()); System.out.println("原對象信息:"+p.toString()); if(p.getWorker().getWorkName().equals(p_clone.getWorker().getWorkName())){ System.out.println("淺複製對象,其引用的對象未複製"); }else{ System.out.println("非淺複製對象,其引用的對象也複製"); } } }
運行結果測試
原對象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]] 克隆對象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]] 修改後的克隆對象信息:Person [name=kucs_clone, age=24, weight=65, height=170, worker=Worker [workName=asianinfo_clone, department=cboss]] 原對象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asianinfo_clone, department=cboss]] 淺複製對象,其引用的對象未複製
結果說明:淺克隆以後的對象與原對象不是同一個對象。修改其中一個對象的值對另外一個對象沒有影響。this
淺克隆中其引用的對象未複製,仍是指向同一個對象。spa
對淺複製示例代碼作了調整code
package org.wem.im; /** * * <p> * Title: Person<br> * Copyright: Copyright (c) 2016<br> * Company: <br> * </p> * * <p> * Description: 測試Java對象深度克隆 * </p> * * @version v1.0.0 * @author kucs * @date 2016年9月30日下午2:45:22 * * Modification History: *---------------------------------------------------------* * */ public class Person implements Cloneable { class Worker implements Cloneable{ private String workName; private String department; public String getWorkName() { return workName; } public void setWorkName(String workName) { this.workName = workName; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub return super.clone(); } @Override public String toString() { return "Worker [workName=" + workName + ", department=" + department + "]"; } } private String name; private String age; private String weight; private String height; private Worker worker; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getWeight() { return weight; } public void setWeight(String weight) { this.weight = weight; } public String getHeight() { return height; } public void setHeight(String height) { this.height = height; } public Worker getWorker() { return worker; } public void setWorker(Worker worker) { this.worker = worker; } @Override protected Object clone() throws CloneNotSupportedException { // TODO Auto-generated method stub Person p = (Person) super.clone(); p.worker = (Worker) worker.clone(); return p; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", weight=" + weight + ", height=" + height + ", worker=" + worker + "]"; } public static void main(String[] args) throws CloneNotSupportedException { Person p = new Person(); Worker worker = p.new Worker(); worker.setWorkName("asiainfo"); worker.setDepartment("cboss"); p.setWorker(worker); p.setName("kucs"); p.setAge("24"); p.setWeight("65"); p.setHeight("170"); Person p_clone = (Person) p.clone(); System.out.println("原對象信息:"+p.toString()); System.out.println("克隆對象信息:"+p_clone.toString()); //修改p_clone對象的值 p_clone.setName("kucs_clone"); //修改對象引用的對象的值 worker.setWorkName("asianinfo_clone"); System.out.println("修改後的克隆對象信息:"+p_clone.toString()); System.out.println("原對象信息:"+p.toString()); if(p.getWorker().getWorkName().equals(p_clone.getWorker().getWorkName())){ System.out.println("淺複製對象,其引用的對象未複製"); }else{ System.out.println("非淺複製對象,其引用的對象也複製"); } } }
運行結果:對象
原對象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]] 克隆對象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]] 修改後的克隆對象信息:Person [name=kucs_clone, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]] 原對象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asianinfo_clone, department=cboss]] 非淺複製對象,其引用的對象也複製
結果說明:深克隆中,對克隆後的對象修改值,不影響原對象的值。修改克隆後的對象引用的值,對原對象引用的對象也沒有影響。接口
3.利用串行化來作深複製ip
這主要是爲了不重寫比較複雜的深複製clone()方法。把對象寫到流裏的過程是串行化過程(Serialization),把對象從流中讀取出來是並行化(Deserialization)過程。
注意:寫在流裏的對象時一個拷貝,而原對象仍然存在jvm中,所以串行化過程只是一個對象的拷貝。
在Java語言中,深複製一個對象,經常能夠先使用對象實現Serializable接口,而後把對象寫到一個流裏,再從流裏讀取出來,即可以重建對象。
package org.wem.im; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /** * * <p> * Title: Person<br> * Copyright: Copyright (c) 2016<br> * Company: <br> * </p> * * <p> * Description: 測試Java對象克隆 * </p> * * @version v1.0.0 * @author kucs * @date 2016年9月30日下午2:28:22 * * Modification History: *---------------------------------------------------------* * */ public class Person implements Serializable { class Worker implements Serializable{ private String workName; private String department; public String getWorkName() { return workName; } public void setWorkName(String workName) { this.workName = workName; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } @Override public String toString() { return "Worker [workName=" + workName + ", department=" + department + "]"; } } private String name; private String age; private String weight; private String height; private Worker worker; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getWeight() { return weight; } public void setWeight(String weight) { this.weight = weight; } public String getHeight() { return height; } public void setHeight(String height) { this.height = height; } public Worker getWorker() { return worker; } public void setWorker(Worker worker) { this.worker = worker; } public Object deepClone() throws IOException, ClassNotFoundException{ //將對象寫到流 ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(this); //從流裏讀取處理啊 ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi = new ObjectInputStream(bi); return oi.readObject(); } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", weight=" + weight + ", height=" + height + ", worker=" + worker + "]"; } public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException { Person p = new Person(); Worker worker = p.new Worker(); worker.setWorkName("asiainfo"); worker.setDepartment("cboss"); p.setWorker(worker); p.setName("kucs"); p.setAge("24"); p.setWeight("65"); p.setHeight("170"); Person p_clone = (Person) p.deepClone(); System.out.println("原對象信息:"+p.toString()); System.out.println("克隆對象信息:"+p_clone.toString()); //修改p_clone對象的值 p_clone.setName("kucs_clone"); //修改對象引用的對象的值 worker.setWorkName("asianinfo_clone"); System.out.println("修改後的克隆對象信息:"+p_clone.toString()); System.out.println("原對象信息:"+p.toString()); if(p.getWorker().getWorkName().equals(p_clone.getWorker().getWorkName())){ System.out.println("淺複製對象,其引用的對象未複製"); }else{ System.out.println("非淺複製對象,其引用的對象也複製"); } } }
運行結果
原對象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]] 克隆對象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]] 修改後的克隆對象信息:Person [name=kucs_clone, age=24, weight=65, height=170, worker=Worker [workName=asiainfo, department=cboss]] 原對象信息:Person [name=kucs, age=24, weight=65, height=170, worker=Worker [workName=asianinfo_clone, department=cboss]] 非淺複製對象,其引用的對象也複製