Python知識(shí)分享網(wǎng) - 專業(yè)的Python學(xué)習(xí)網(wǎng)站 學(xué)Python,上Python222
《劍指offer》Java淺拷貝和深拷貝 PDF 下載
匿名網(wǎng)友發(fā)布于:2024-01-23 09:39:45
(侵權(quán)舉報(bào))
(假如點(diǎn)擊沒反應(yīng),多刷新兩次就OK!)

《劍指offer》Java淺拷貝和深拷貝 PDF 下載  圖1

 

 

 

資料內(nèi)容:

 

關(guān)于淺拷貝和深拷貝 淺拷貝和深拷貝其實(shí)就是在 引用 的這個(gè)基礎(chǔ)上來做區(qū)分的,如果在拷貝的時(shí)候,只對(duì)基本數(shù)據(jù)類型進(jìn)行 拷貝,對(duì)引用數(shù)據(jù)類型只是進(jìn)行了引用的傳遞,沒有真正的創(chuàng)建一個(gè)新的對(duì)象,這種拷貝方式就認(rèn)為 是 淺拷貝 。反之,在對(duì)引用數(shù)據(jù)類型進(jìn)行拷貝的時(shí)候,創(chuàng)建了一個(gè)新的對(duì)象,并且復(fù)制其內(nèi)的成員變 量,這種拷貝方式就被認(rèn)為是 深拷貝 。 淺拷貝 那么如何實(shí)現(xiàn) 淺拷貝(Shallow copy) 呢?很簡(jiǎn)單,就是在需要拷貝的類上實(shí)現(xiàn) Cloneable 接口并重寫其 clone() 方法就可以了。 下面我們對(duì) Food 類進(jìn)行修改,我們讓他實(shí)現(xiàn) Cloneable 接口,并重寫 clone() 方法。 public class Food implements Cloneable{ ... @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } ... } 然后在測(cè)試類中的代碼如下 Food milk = new Food("milk",1,"fragrance"); Food food = (Food)milk.clone(); System.out.println("milk = " + milk); System.out.println("food = " + food); 可以看到,現(xiàn)在的 food 對(duì)象是由 milk 對(duì)象拷貝出來的,那么此時(shí)的 food 對(duì)象和 milk 對(duì)象是同一個(gè)對(duì) 象嗎?我們通過打印,可以看到這兩個(gè)對(duì)象的原生 hashcode 。 milk = com.cxuan.objectclone.Food@3cd1a2f1 food = com.cxuan.objectclone.Food@4d7e1886 可以發(fā)現(xiàn),food 和 milk 并不是同一個(gè)對(duì)象,那 milk 中還有三個(gè)屬性值,這三個(gè)屬性值在 food 中是不 是也一樣呢?為了驗(yàn)證這個(gè)猜想,我們重寫了 toString 方法。 @Override public String toString() { return "Food{" + "name='" + name + '\'' + ", num=" + num + ", taste='" + taste + '\'' + '}'; } 然后再次打印 food 和 milk ,可以觀察到如下結(jié)果 milk = Food{name='milk', num=1, taste='fragrance'} food = Food{name='milk', num=1, taste='fragrance'} 嗯哼,雖然看起來"cxuan 哥"和"cuan 哥"是兩種完全不同的稱呼!但是他們卻有一種共同的能力:寫 作! 我們還是通過圖示來說明一下: 這幅圖看出門道了么?在堆區(qū)分別出現(xiàn)了兩個(gè) Food 對(duì)象,這同時(shí)表明 clone 方法會(huì)重新創(chuàng)建一個(gè)對(duì)象 并為其分配一塊內(nèi)存區(qū)域;雖然出現(xiàn)了兩個(gè)對(duì)象,但是兩個(gè)對(duì)象中的屬性值是一樣的,這也是換湯不換 藥,雖然湯和藥是不同的東西(對(duì)象),但是他們都溶于水(屬性值)。 深拷貝 雖然淺拷貝是一種換湯不換藥的說法,但是在 Java 世界中還是有一種說法是。。。。。。是啥來著? 詞窮了。。。。。。 哦對(duì),還有一種改頭換面的形式,它就是我們所熟悉的 深拷貝(Deep copy) ,先來拋出一下深拷貝的定 義:在進(jìn)行對(duì)象拷貝的基礎(chǔ)上,對(duì)對(duì)象的成員變量也依次拷貝的方式被稱為深拷貝。 哈哈哈哈,這故作高深的深拷貝原來就是在淺拷貝的基礎(chǔ)上再復(fù)制一下它的屬性值啊,我還以為是啥高 深的東西呢!上代碼! 我們先增加一個(gè)飲品類 Drink 。 public class Drink implements Cloneable { String name; get and set() @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } toString() } 然后更改一下 Food 類,因?yàn)?Drink 也算是 Food ,所以我們?cè)?Food 類中增加對(duì) Drink 的引用,然后再 修改 get set 、toString 、clone 、構(gòu)造方法,修改后的 Food 類代碼如下 public class Food implements Cloneable{ String name; int num; String taste; Drink drink; public Food(String name, int num, String taste,Drink drink) { this.name = name; this.num = num; this.taste = taste; this.drink = drink; } get and set... @Override protected Object clone() throws CloneNotSupportedException { Food food = (Food)super.clone(); food.drink = (Drink) drink.clone(); return super.clone(); } @Override public String toString() { return "Food{" + "name='" + name + '\'' + ", num=" + num + ", taste='" + taste + '\'' + ", drink=" + drink + '}'; } } 可以看到最大的改變是 clone 方法,我們?cè)?clone 方法中,實(shí)現(xiàn)了對(duì) Food 對(duì)象的拷貝,同時(shí)也實(shí)現(xiàn)了 對(duì) Drink 對(duì)象的拷貝,這就是我們上面所說的復(fù)制對(duì)象并復(fù)制對(duì)象的成員變量。