Java實(shí)現(xiàn)克隆的三種方式實(shí)例總結(jié)
本文實(shí)例講述了Java實(shí)現(xiàn)克隆的三種方式。分享給大家供大家參考,具體如下:
1、淺復(fù)制(淺克?。┻@種淺復(fù)制,其實(shí)也就是把被復(fù)制的這個(gè)對(duì)象的一些變量值拿過來了。最后生成student2還是一個(gè)新的對(duì)象。
public class CloneTest1 { public static void main(String[] args) throws Exception { Student1 student = new Student1(); student.setAge(24); student.setName("niesong"); Student1 student2 = (Student1)student.clone(); //這個(gè)是調(diào)用下面的那個(gè)方法,然后把這個(gè)這個(gè)對(duì)象Clone到student System.out.println("Age:" + student2.getAge() + " " + "Name:" + student2.getName()); System.out.println("---------------------"); student2.setAge(23); //克隆后得到的是一個(gè)新的對(duì)象,所以重新寫的是student2這個(gè)對(duì)象的值 System.out.println(student.getAge()); System.out.println(student2.getAge()); } } //克隆的對(duì)象必須實(shí)現(xiàn)Cloneable這個(gè)接口,而且需要重寫clone方法 class Student1 implements Cloneable { private int age; //定義為private說明這個(gè)成員變量只能被被當(dāng)前類中訪問,如果外部需要獲得,那么就只能通過getAge方法進(jìn)行獲取 private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public Object clone() throws CloneNotSupportedException { Object object = super.clone(); return object; } }
運(yùn)行結(jié)果:
2、深復(fù)制(情況1使用的是在克隆的時(shí)候手動(dòng)進(jìn)行深克?。?/p>
public class CloneTest2 { public static void main(String[] args) throws Exception { Teacher teacher = new Teacher(); teacher.setAge(40); teacher.setName("teacher zhang"); Student2 student2 = new Student2(); student2.setAge(14); student2.setName("lisi"); student2.setTeacher(teacher); Student2 student3 = (Student2)student2.clone(); //這里是深復(fù)制,所以這時(shí)候Student2中的teacher就是teacher這個(gè)對(duì)象的一個(gè)復(fù)制,就和student3是student2的一個(gè)復(fù)制 //所以下面teacher.setName只是對(duì)他原來的這個(gè)對(duì)象更改,但是復(fù)制的那個(gè)并沒有更改 System.out.println(student3.getAge()); System.out.println(student3.getName()); System.out.println(student3.getTeacher().getAge()); teacher.setName("teacher niesong");//不會(huì)又任何影響 System.out.println(student3.getTeacher().getName()); } } class Student2 implements Cloneable { private int age; private String name; private Teacher teacher; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Teacher getTeacher() { return teacher; } public void setTeacher(Teacher teacher) { this.teacher = teacher; } @Override public Object clone() throws CloneNotSupportedException { //這一步返回的這個(gè)student2還只是一個(gè)淺克隆, Student2 student2 = (Student2)super.clone(); //然后克隆的過程中獲得這個(gè)克隆的student2,然后調(diào)用這個(gè)getTeacher這個(gè)方方法得到這個(gè)Teacher對(duì)象。然后實(shí)現(xiàn)克隆。在設(shè)置到這個(gè)student2中的Teacher。 //這樣實(shí)現(xiàn)了雙層克隆使得那個(gè)teacher對(duì)象也得到了復(fù)制。 student2.setTeacher((Teacher)student2.getTeacher().clone()); //雙層克隆使得那個(gè)teacher對(duì)象也得到了復(fù)制 return student2; } } class Teacher implements Cloneable { private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } }
運(yùn)行結(jié)果:
3、利用serializable實(shí)現(xiàn)深復(fù)制(這個(gè)是利用Serializable,利用序列化的方式來實(shí)現(xiàn)深復(fù)制(深克?。?,在其中利用了Io流的方式將這個(gè)對(duì)象寫到IO流里面,然后在從IO流里面讀取,這樣就實(shí)現(xiàn)了一個(gè)復(fù)制,然后實(shí)現(xiàn)序列化的這個(gè)會(huì)將引用的那個(gè)對(duì)象也一并進(jìn)行深復(fù)制,這樣就實(shí)現(xiàn)了這個(gè)機(jī)制,同時(shí)在IO里面讀取數(shù)據(jù)的時(shí)候還使用了裝飾者模式)
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class CloneTest3 { public static void main(String[] args) throws Exception { Teacher3 teacher3 = new Teacher3(); teacher3.setAge(23); teacher3.setName("niesong"); Student3 student3 = new Student3(); student3.setAge(50); student3.setName("wutao"); student3.setTeacher3(teacher3); Student3 ss = (Student3)student3.deepCopt(); System.out.println(ss.getAge()); System.out.println(ss.getName()); System.out.println("---------------------"); System.out.println(ss.getTeacher3().getAge()); System.out.println(ss.getTeacher3().getName()); System.out.println("-----------------------"); ss.getTeacher3().setAge(7777); ss.getTeacher3().setName("hhhhh"); System.out.println(teacher3.getAge()); System.out.println(teacher3.getName()); //雖然上面的已經(jīng)改了,但是改的是那個(gè)復(fù)制對(duì)象后的那個(gè)里面的,然后那個(gè)原來的那個(gè)里面的并沒有改,下面驗(yàn)證::: System.out.println("-----------------"); System.out.println(ss.getTeacher3().getAge()); System.out.println(ss.getTeacher3().getName()); } } class Teacher3 implements Serializable { // 上面的那個(gè)警告可以直接消除,除了使用在設(shè)置中不顯示這個(gè)警告,還可以使用下面的這兩條語句中的任何一條語句 // 這個(gè)serialVersionUID為了讓該類別Serializable向后兼容 // private static final long serialVersionUID = 1L; // private static final long serialVersionUID = 8940196742313994740L; private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } } class Student3 implements Serializable { private static final long serialVersionUID = 1L; private int age; private String name; private Teacher3 teacher3; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Teacher3 getTeacher3() { return teacher3; } public void setTeacher3(Teacher3 teacher3) { this.teacher3 = teacher3; } //使得序列化student3的時(shí)候也會(huì)將teacher序列化 public Object deepCopt()throws Exception { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); //將當(dāng)前這個(gè)對(duì)象寫到一個(gè)輸出流當(dāng)中,,因?yàn)檫@個(gè)對(duì)象的類實(shí)現(xiàn)了Serializable這個(gè)接口,所以在這個(gè)類中 //有一個(gè)引用,這個(gè)引用如果實(shí)現(xiàn)了序列化,那么這個(gè)也會(huì)寫到這個(gè)輸出流當(dāng)中 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject(); //這個(gè)就是將流中的東西讀出類,讀到一個(gè)對(duì)象流當(dāng)中,這樣就可以返回這兩個(gè)對(duì)象的東西,實(shí)現(xiàn)深克隆 } }
運(yùn)行結(jié)果:
更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java面向?qū)ο蟪绦蛟O(shè)計(jì)入門與進(jìn)階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
Spring?Boot如何排除自動(dòng)加載數(shù)據(jù)源
這篇文章主要介紹了Spring?Boot如何排除自動(dòng)加載數(shù)據(jù)源,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12詳談Array和ArrayList的區(qū)別與聯(lián)系
下面小編就為大家?guī)硪黄斦凙rray和ArrayList的區(qū)別與聯(lián)系。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06Java的Struts框架中登陸功能的實(shí)現(xiàn)和表單處理器的使用
這篇文章主要介紹了Java的Struts框架中登陸功能的實(shí)現(xiàn)和表單處理器的使用,Struts框架是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下2015-12-12Servlet實(shí)現(xiàn)簡單的用戶登錄功能實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于利用Servlet實(shí)現(xiàn)簡單的用戶登錄功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12如何解決maven搭建一直處于running:..狀態(tài)問題
在使用Maven搭建項(xiàng)目時(shí),有時(shí)會(huì)遇到一直處于加載狀態(tài)的情況,通過修改設(shè)置可以解決這個(gè)問題,具體步驟為:1. 打開File->Settings->Build, Execution, Deployment->Maven->running,然后在VMOptions中填寫"-DarchetypeCatalog=internal"2024-09-09詳解SpringBoot Controller接收參數(shù)的幾種常用方式
這篇文章主要介紹了詳解SpringBoot Controller接收參數(shù)的幾種常用方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10