Java對(duì)象深復(fù)制與淺復(fù)制實(shí)例詳解
Java對(duì)象深復(fù)制與淺復(fù)制實(shí)例詳解
我們?cè)谟龅揭恍I(yè)務(wù)場(chǎng)景的時(shí)候經(jīng)常需要對(duì)對(duì)象進(jìn)行復(fù)制,對(duì)于對(duì)象的復(fù)制一般有兩種方式,深復(fù)制和淺復(fù)制
淺復(fù)制:對(duì)象的復(fù)制僅是對(duì)象本身,對(duì)象引用的其它對(duì)方并不會(huì)復(fù)制。
深復(fù)制:對(duì)象的復(fù)制包含對(duì)象引用的對(duì)象。
Java所有對(duì)象的基類提供了clone方法,但是這個(gè)方法是protected native修飾,因此只暴露給之類去重寫,外部是無(wú)法直接調(diào)用的。
我們現(xiàn)在來(lái)測(cè)試兩種復(fù)制,首選是淺復(fù)制,淺復(fù)制要實(shí)現(xiàn)Cloneable接口。
// 課程對(duì)象 class Class { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } // 學(xué)生對(duì)象 class User implements Cloneable { private String name; private Long id; // 課程引用 private Class c; public Class getC() { return c; } public void setC(Class c) { this.c = c; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public int hashCode() { return super.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof User) { User user = (User) obj; if (this.id == user.getId() && this.getName() == user.getName()) { return true; } if (user.getId().equals(this.id) && user.getName().equals(this.name)) { return true; } return false; } else return false; } }
我們來(lái)測(cè)試:
User user1 = new User(); User user2 = user1; User user3 = (User) user1.clone(); System.out.println(user1 == user2); System.out.println(user3 == user1); System.out.println(user3.equals(user1)); System.out.println(user3.getName() == user3.getName());// true,淺復(fù)制 Class c = new Class(); c.setName("語(yǔ)文"); user1.setC(c); // 測(cè)試復(fù)制深度 User user4 = (User) user1.clone(); System.out.println(user4.getC() == user1.getC()); // true,說(shuō)明引用的對(duì)象依然是同一個(gè)對(duì)象
對(duì)象的復(fù)制并沒(méi)復(fù)制引用所指向的對(duì)象class,復(fù)制出來(lái)的引用指向的同一個(gè)地址。
深復(fù)制采用序列化與反序列的方式去獲取,也有種說(shuō)法類似于腌菜,用流的方式腌制進(jìn)去又取出來(lái),實(shí)現(xiàn)深度復(fù)制。
class Car implements Serializable { /** * */ private static final long serialVersionUID = 42342L; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } // 深復(fù)制 class People implements Serializable{ /** * */ private static final long serialVersionUID = 543535212412L; private Car car; public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } public People deepClone() throws IOException, ClassNotFoundException { // 腌制 ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out); oos.writeObject(this); // 取出 ByteArrayInputStream input = new ByteArrayInputStream(out.toByteArray()); ObjectInputStream ois = new ObjectInputStream(input); return (People) ois.readObject(); } }
測(cè)試深復(fù)制:
// 深復(fù)制 Car car = new Car(); car.setName("benz"); People p = new People(); p.setCar(car); try { People p2 = p.deepClone(); System.out.println(p2.getCar() == p.getCar()); // false,說(shuō)明引用的對(duì)象也進(jìn)行了復(fù)制 } catch (ClassNotFoundException | IOException e) { e.printStackTrace(); }
例外提及一下生成對(duì)象的五種辦法:
1.new
2.Class類的newInstance
3.Constructor類newInstance
4.Clone方式
5.反序列化的方式
其中2與3即是反射的方式。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
- 利用Java反射機(jī)制實(shí)現(xiàn)對(duì)象相同字段的復(fù)制操作
- Java對(duì)象的復(fù)制三種方式(小結(jié))
- Java編程實(shí)現(xiàn)對(duì)象克?。◤?fù)制)代碼詳解
- Java中對(duì)象的深復(fù)制(深克?。┖蜏\復(fù)制(淺克?。┙榻B
- 深入java對(duì)象復(fù)制的分析
- Java基礎(chǔ)之面向?qū)ο髾C(jī)制(多態(tài)、繼承)底層實(shí)現(xiàn)
- Java MapStruct解了對(duì)象映射的毒
- 詳解Java對(duì)象的內(nèi)存布局
- Java基礎(chǔ)詳解之面向?qū)ο蟮哪切┦聝?/a>
- 深入理解Java對(duì)象復(fù)制
相關(guān)文章
使用eclipse導(dǎo)入javaWeb項(xiàng)目的圖文教程
這篇文章主要介紹了如何使用eclipse導(dǎo)入別人的javaWeb項(xiàng)目,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07數(shù)據(jù)庫(kù)連接超時(shí)java處理的兩種方式
這篇文章主要介紹了數(shù)據(jù)庫(kù)連接超時(shí)java處理的兩種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04Java中的轉(zhuǎn)換流InputStreamReader解讀
InputStreamReader是Java.io包中的一個(gè)類,用于將字節(jié)輸入流轉(zhuǎn)換為字符輸入流,它繼承自java.io.Reader類,提供了兩種構(gòu)造方法,可以使用默認(rèn)或指定字符集創(chuàng)建實(shí)例,常用方法包括讀取字符、判斷是否準(zhǔn)備好讀取數(shù)據(jù)和關(guān)閉流2024-09-09java中vector與hashtable操作實(shí)例分享
java中vector與hashtable操作實(shí)例,有需要的朋友可以參考一下2014-01-01Java回調(diào)函數(shù)原理實(shí)例與代理模式的區(qū)別講解
今天小編就為大家分享一篇關(guān)于Java回調(diào)函數(shù)原理實(shí)例與代理模式的區(qū)別講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02java實(shí)現(xiàn)超市商品庫(kù)存管理平臺(tái)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)超市商品庫(kù)存管理平臺(tái),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10