clone 物件的使用

2021-09-26 07:29:06 字數 2619 閱讀 1710

當 person p1 = p;執行之後, 是建立了乙個新的物件嗎? 首先看列印結果:

可以看出,列印的位址值是相同的,既然位址都是相同的,那麼肯定是同乙個物件。p 和 p1 只是引用而已,他們 都指向了乙個相同的物件 person(23, 「zhang」) 。 可以把這種現象叫做引用的複製。上面**執行完成之後, 內 存中的情景如下圖所示:

1. person p = new person(23, "zhang"); 2. person p1 = p;

3. system.out.println(p);

4. system.out.println(p1);

1.com.itheima.person@2f9ee1ac

2.com.itheima.person@2f9ee1ac

而下面的**是真真正正的轉殖了乙個物件。

1.person p = new person(23, "zhang");

2.person p1 = (person) p.clone();

3.system.out.println(p);

4.system.out.println(p1);

從列印結果可以看出,兩個物件的位址是不同的,也就是說建立了新的物件, 而不是把原物件的位址賦給了乙個 新的引用變數:

以上**執行完成後, 記憶體中的情景如下圖所示:

上面的示例**中,person 中有兩個成員變數,分別是 name 和 age, name 是 string 型別, age 是 int 類 型。**非常簡單,如下所示:

public class person implements cloneable

public person(){}

public int getage()

public string getname()

@override

protected object clone() throws clonenotsupportedexception

}

由於 age 是基本資料型別,那麼對它的拷貝沒有什麼疑議,直接將乙個 4 位元組的整數值拷貝過來就行。但是 name是 string 型別的, 它只是乙個引用, 指向乙個真正的 string 物件,那麼對它的拷貝有兩種方式: 直接將原物件中 的 name 的引用值拷貝給新物件的 name 字段, 或者是根據原 person 物件中的 name 指向的字串物件建立乙個 新的相同的字串物件,將這個新字串物件的引用賦給新拷貝的 person 物件的 name 字段。這兩種拷貝方式分別 叫做淺拷貝和深拷貝。深拷貝和淺拷貝的原理如下圖所示:

下面通過**進行驗證。如果兩個 person 物件的 name 的位址值相同, 說明兩個物件的 name 都指向同乙個string 物件,也就是淺拷貝, 而如果兩個物件的 name 的位址值不同, 那麼就說明指向不同的 string 物件, 也就 是在拷貝 person 物件的時候, 同時拷貝了 name 引用的 string 物件, 也就是深拷貝。驗證**如下:

person p = new person(23, "zhang"); 

person p1 = (person) p.clone();

string result = p.getname() == p1.getname() ? "clone 是淺拷貝的" : "clone 是深拷貝的"; system.out.println(result);

列印結果為: clone 是淺拷貝的

所以,clone 方法執行的是淺拷貝, 在編寫程式時要注意這個細節。

由上一節的內容可以得出如下結論:如果想要深拷貝乙個物件,這個物件必須要實現 cloneable 介面,實現 clone方法,並且在 clone 方法內部,把該物件引用的其他物件也要 clone 乙份,這就要求這個被引用的物件必須也要實現cloneable 介面並且實現 clone 方法。那麼,按照上面的結論,實現以下** body 類組合了 head 類,要想深拷貝body 類,必須在 body 類的 clone 方法中將 head 類也要拷貝乙份。**如下:

static class body implements cloneable

public body(head head)

@override

protected object clone() throws clonenotsupportedexception

}static class head implements cloneable

@override

protected object clone() throws clonenotsupportedexception

}public static void main(string args) throws clonenotsupportedexception

列印結果為:

1. body == body1 : false

2. body.head == body1.head : false

物件屬性使用 clone

類包含的例項字段屬於某個類型別,這種情況相信大家都見到過。通常,該例項字段設定為private,類方法中含有對其get,set方法。有個類將其他類作為自己的私有屬性,該類沒有使用set方法,私有屬性類物件居然就發生了變化,可不可怕,例子如下 public class test class peopl...

物件的轉殖(clone)

讓物件obj1轉殖物件obj var obj var obj1 function clone origin,target clone obj,obj1 使用for.in把obj物件的每乙個屬性值提取出來並賦值給物件obj1,這就完成了轉殖。關於以上那個轉殖,為了防止使用者不傳target的形參或者是...

java 實現物件的clone

物件的 賦值只是傳遞引用,其本質還是指向乙個引用。當改變乙個物件的值時,另乙個也會改變 例如 public class student implements cloneable catch exception e return s public string getname public void ...