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

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

 

 

 

資料內(nèi)容:

 

關(guān)于淺拷貝和深拷貝 淺拷貝和深拷貝其實就是在 引用 的這個基礎(chǔ)上來做區(qū)分的,如果在拷貝的時候,只對基本數(shù)據(jù)類型進行 拷貝,對引用數(shù)據(jù)類型只是進行了引用的傳遞,沒有真正的創(chuàng)建一個新的對象,這種拷貝方式就認為 是 淺拷貝 。反之,在對引用數(shù)據(jù)類型進行拷貝的時候,創(chuàng)建了一個新的對象,并且復(fù)制其內(nèi)的成員變 量,這種拷貝方式就被認為是 深拷貝 。 淺拷貝 那么如何實現(xiàn) 淺拷貝(Shallow copy) 呢?很簡單,就是在需要拷貝的類上實現(xiàn) Cloneable 接口并重寫其 clone() 方法就可以了。 下面我們對 Food 類進行修改,我們讓他實現(xiàn) Cloneable 接口,并重寫 clone() 方法。 public class Food implements Cloneable{ ... @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } ... } 然后在測試類中的代碼如下 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 對象是由 milk 對象拷貝出來的,那么此時的 food 對象和 milk 對象是同一個對 象嗎?我們通過打印,可以看到這兩個對象的原生 hashcode 。 milk = com.cxuan.objectclone.Food@3cd1a2f1 food = com.cxuan.objectclone.Food@4d7e1886 可以發(fā)現(xiàn),food 和 milk 并不是同一個對象,那 milk 中還有三個屬性值,這三個屬性值在 food 中是不 是也一樣呢?為了驗證這個猜想,我們重寫了 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)了兩個 Food 對象,這同時表明 clone 方法會重新創(chuàng)建一個對象 并為其分配一塊內(nèi)存區(qū)域;雖然出現(xiàn)了兩個對象,但是兩個對象中的屬性值是一樣的,這也是換湯不換 藥,雖然湯和藥是不同的東西(對象),但是他們都溶于水(屬性值)。 深拷貝 雖然淺拷貝是一種換湯不換藥的說法,但是在 Java 世界中還是有一種說法是。。。。。。是啥來著? 詞窮了。。。。。。 哦對,還有一種改頭換面的形式,它就是我們所熟悉的 深拷貝(Deep copy) ,先來拋出一下深拷貝的定 義:在進行對象拷貝的基礎(chǔ)上,對對象的成員變量也依次拷貝的方式被稱為深拷貝。 哈哈哈哈,這故作高深的深拷貝原來就是在淺拷貝的基礎(chǔ)上再復(fù)制一下它的屬性值啊,我還以為是啥高 深的東西呢!上代碼! 我們先增加一個飲品類 Drink 。 public class Drink implements Cloneable { String name; get and set() @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } toString() } 然后更改一下 Food 類,因為 Drink 也算是 Food ,所以我們在 Food 類中增加對 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 方法,我們在 clone 方法中,實現(xiàn)了對 Food 對象的拷貝,同時也實現(xiàn)了 對 Drink 對象的拷貝,這就是我們上面所說的復(fù)制對象并復(fù)制對象的成員變量。