2010-08-13 51 views
2

的Java醫生說 -Cloneable的行爲

Object類本身不 實現接口Cloneable,所以 調用對象 其類的克隆方法將導致 對象在運行拋出異常時間。

這是爲什麼Object類中的clone方法受到保護的原因?是這樣嗎 ?

這意味着任何不實現cloneable的類將在調用clone方法時拋出CloneNotSupported異常。

我跑了一個測試程序

public class Test extends ABC implements Cloneable{ 

    @Override 
    public Object clone() throws CloneNotSupportedException { 
     System.out.println("calling super.clone"); 
      return super.clone(); 
    } 

    public static void main(String[] args) { 
     Test t = new Test(); 
     try{ 
     t.clone(); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
class ABC{ 

} 

從測試類的clone方法super.clone被調用?

爲什麼不拋出異常?

+0

[已關閉]?這不是一個論壇。你應該選擇一個最好的答案並接受它。 – musiKk 2010-08-13 12:07:43

+0

[關閉]在問題標題的末尾有一個非常具體的含義StackOverflow。這意味着至少有五個擁有關閉權限的用戶或者至少一個主持人已經決定您的問題不符合StackOverflow上預期的標準。這目前不適用於您的問題,因此我將刪除問題標題前面的[Closed]標籤。如果您真的想讓[Closed]標籤留下,請將其放回原處,我不會再進行第二次編輯 - 或者要求我撤消更改,我會這樣做。 – richj 2010-09-01 01:05:18

回答

2

繼承樹。它檢查實例t是否實現了Cloneable接口。既然它實現了方法,不會拋出異常。

1

Cloneable接口是一個標記接口,指示實現類支持克隆方法。 super.clone()不會引發異常的原因是它所調用的基礎對象是繼承的可複製對象。

從的Javadoc:

一個類實現了Cloneable接口,以指示它是合法的Object.clone()方法,該方法使該實例的現場換場副本類。

在未實現Cloneable接口的實例上調用Object的克隆方法會導致引發異常CloneNotSupportedException。

看:Test實例t看起來像

Object 
    ABC 
    Test 

Test還實現Cloneable這意味着當你調用方法super.clone()Objectclone方法將被調用的Cloneable (Java Platform SE 6)

1

因爲您的班級實施了Cloneable。從JavadocCloneable的:

一個類實現了Cloneable接口,以指示它是合法的,該方法使該類的實例的現場換場副本Object.clone()方法。

所以這允許使用Objectclone()方法。這是(再次根據Javadoc)只是一個約定來覆蓋clone()。如果您不覆蓋它,並且Objectclone()方法執行字段對字段複製,則如果其中一個字段本身不可複製,則仍可能獲得CloneNotSupportedException。因此,重寫它是個好建議。

1

爲什麼對象類protected中的克隆方法?

,使得選擇支持克隆類不被迫揭露它的公共的API中。

如您的示例所示,允許子類覆蓋比該方法的繼承版本更多訪問權限的方法。你不能以這種方式減少方法的訪問。

這意味着任何不實現可克隆類的類將在調用其克隆方法時拋出CloneNotSupported異常。

這是正確的。

從Class Test的clone方法super.clone被調用?

這是正確的。

爲什麼不拋出異常?

因爲你已經聲明你的類實現了Cloneable。如果你沒有這樣做,它會拋出一個異常...假設你的克隆方法仍然叫super.clone()

1

這可能給你答案爲什麼是方法保護 why is clone method protected

因爲你實現Cloneable它不會拋出異常。來自Cloneable文檔:

「一個類實現了Cloneable接口,以向Object.clone()方法表明該方法是合法的,以便爲該類的實例創建字段對字段副本。被扔在一個實例 調用對象的clone方法沒有實現在異常CloneNotSupportedException的Cloneable接口的結果。「

但正如你實現它,你告訴對象實現,它的法律作出字段之間的副本,所以它不會拋出異常。

1

我會說一個很好的問題來混淆採訪者:)。

至於它不拋出異常的原因。以對象的方式來思考它。你的t對象是實現可複製的類Test。當你調用super.clone方法時,它仍然是Test類的一個對象,所以沒有理由拋出CloneNotSupported異常。如果它是Object類本身的對象,它會拋出異常。