java深度克隆_Java深入学习26:Java深度克隆
Java深入學習26:Java深度克隆
深克隆和淺克隆區別
淺克隆: 只copy對象引用,不copy對象本身。即對象地址不變,仍然只存在一個對象。
深克隆: 不僅拷貝對象本身,而且拷貝對象包含的引用指向的所有對象。
深克隆的兩個方案
方案1——實現Cloneable接口,重寫Object類地?clone()方法
分如下三步
1. 對象的類實現Cloneable接口(必須,否則會拋出CloneNotSupportedException異常);
2. 覆蓋Object類的clone()方法 (覆蓋clone()方法,將訪問修飾符改為public,默認是protected);
3. 在clone()方法中調用super.clone();
public classCloneTest {public static void main(String[] args) throwsCloneNotSupportedException {
Student stu= new Student("A");
Student deep= stu.clone();//深克隆
Student shallow = stu;//淺克隆
shallow.setName("B");
System.out.println("original: " + stu);//Student{name='B'}
System.out.println("deep: " + deep);//Student{name='A'}
System.out.println("shallow: " + shallow);//Student{name='B'}
}
}class Student implementsCloneable{privateString name;publicStudent(String name) {this.name =name;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}
@Overridepublic Student clone() throws CloneNotSupportedException {
return (Student) super.clone();
}
@OverridepublicString toString() {return "Student{" +
"name='" + name + '\'' +
'}';
}
}
深克隆的多級深克隆問題:
重寫clone()方法,只會深克隆類和類中所有非基本數據類型的屬性對應的類。對于類中的屬性對應的類,是無法深克隆的,如果深克隆類中的屬性對應的類,需要額外的調用類中的屬性對應的類clone方法
public classCloneTest {public static void main(String[] args) throwsCloneNotSupportedException {
School sch= new School("a",new Student("A"));
School deepSch= sch.clone();//深克隆
School shallowSch = sch;//淺克隆
shallowSch.getStu().setName("B");
System.out.println(sch);//School{name='a', stu=Student{name='B'}}
System.out.println(deepSch);//School{name='a', stu=Student{name='A'}}
System.out.println(shallowSch);//School{name='a', stu=Student{name='B'}}
}
}class School implementsCloneable{privateString name;privateStudent stu;
@Overridepublic School clone() throwsCloneNotSupportedException {//return (School)super.clone();//該方法無法深克隆Sch中的Student
School clone = (School) super.clone();
clone.setStu(this.stu.clone());returnclone;
}publicSchool(String name, Student stu) {this.name =name;this.stu =stu;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}publicStudent getStu() {returnstu;
}public voidsetStu(Student stu) {this.stu =stu;
}
@OverridepublicString toString() {return "School{" +
"name='" + name + '\'' +
", stu=" + stu +
'}';
}
}
方案2——序列化深克隆
什么是序列化?
1- java序列化是指把java對象轉換為字節序列的過程,而java反序列化是指把字節序列恢復為java對象的過程
2- 序列化:對象序列化的最主要的用處就是在傳遞和保存對象的時候,保證對象的完整性和可傳遞性。序列化是把對象轉換成有序字節流,以便在網絡上傳輸或者保存在本地文件中。序列化后的字節流保存的java對象的狀態以及相關的描述信息。序列化機制的核心作用就是對象狀態的保存與重建。
3- 反序列化:客戶端從文件中或網絡上獲得序列化后的對象字節流后,根據字節流中所保存的對象狀態及描述信息,通過反序列化重建對象。
4- 序列化就是把實體對象狀態按照一定的格式寫入到有序字節流,反序列化就是從有序字節流重建對象,恢復對象狀態
import java.io.*;public classSerializeDeepCloneTest {public static voidmain(String[] args) {
SchoolSeri sch= new SchoolSeri("zjut",new StudentSeri("tyj"));
SchoolSeri schSeri= null;
System.out.println(sch);try{
schSeri=SerializeDeepCloneUtil.deepClone(sch);
System.out.println(sch);
}catch(Exception e) {
e.printStackTrace();
}
System.out.println(sch==schSeri);
}
}classSerializeDeepCloneUtil{//序列化深克隆
static T deepClone(T obj){if(obj ==null){return null;
}
T cloneObj= null;//序列化
ByteArrayOutputStream bout = null;
ObjectOutputStream oos= null;try{//創建字節數組輸出流//new ByteArrayOutputStream() Creates a new byte array output stream.
bout = newByteArrayOutputStream();//創建對象輸出流//new ObjectOutputStream(OutputStream out): Creates an ObjectOutputStream that writes to the specified OutputStream.
oos = newObjectOutputStream(bout);//向對象輸出流中寫數據//void writeObject(Object obj): Write the specified object to the ObjectOutputStream.
oos.writeObject(obj);
}catch(IOException e) {
e.printStackTrace();
}finally{
close(oos);
close(bout);
}//反序列化
ByteArrayInputStream bin = null;
ObjectInputStream ois= null;try{//創建字節數組輸入流//new ByteArrayInputStream(byte buf[]): Creates a ByteArrayInputStream so that it uses buf as its buffer array.
bin = newByteArrayInputStream(bout.toByteArray());//創建對象輸入流//new ObjectInputStream(InputStream in): Creates an ObjectInputStream that reads from the specified InputStream.
ois = newObjectInputStream(bin);//從對象輸入流中讀取數據//Object readObject(): Read an object from the ObjectInputStream.
cloneObj =(T)ois.readObject();
}catch (IOException |ClassNotFoundException e) {
e.printStackTrace();
}finally{
close(ois);
close(bin);
}returncloneObj;
}//關閉流
private static voidclose(Closeable closeable){if(closeable != null){try{
closeable.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
}
public class SchoolSeri implementsSerializable{privateString name;privateStudentSeri stu;publicSchoolSeri(String name, StudentSeri stu) {this.name =name;this.stu =stu;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}publicStudentSeri getStu() {returnstu;
}public voidsetStu(StudentSeri stu) {this.stu =stu;
}
@OverridepublicString toString() {return "School{" +
"name='" + name + '\'' +
", stu=" + stu +
'}';
}
}public class StudentSeri implementsSerializable{privateString name;publicStudentSeri(String name) {this.name =name;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}
@OverridepublicString toString() {return "Student{" +
"name='" + name + '\'' +
'}';
}
}
END
總結
以上是生活随笔為你收集整理的java深度克隆_Java深入学习26:Java深度克隆的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java akka_Akka系列(九):
- 下一篇: 炒苍耳子的功效与作用、禁忌和食用方法