2013-05-12 40 views
16

我碰到一個實現Clonable一些類代碼來了,文檔指出:讓我的類實現Cloneable有什麼意義?

一個類實現了Cloneable接口,以指示Object.clone()方法,它是合法的,該方法做一個現場該類的實例的現場副本。 在未實現Cloneable接口的實例上調用Object的克隆方法會導致引發異常CloneNotSupportedException。按照慣例,實現此接口的類應該使用公共方法重寫Object.clone(受保護)。有關覆蓋此方法的詳細信息,請參閱Object.clone()。 請注意,此接口不包含克隆方法。因此,僅憑藉其實現此接口的事實來克隆對象是不可能的。即使克隆方法是反射式調用,也不能保證它會成功。

我不明白在實現這個類的點,正如在文檔中所說的.clone方法沒有在接口中實現,我必須實現它。那麼爲什麼要使用這個類?爲什麼我不會在我的類中編寫一個方法copyClass來使對象複製而不執行此類?

在此先感謝。

+1

您的類實現了Cloneable,因此您可以使用內置的克隆機制,以便其他類可以克隆您的類,而無需知道它的唯一克隆方法。是的,這是一種奇怪的管理方式,但部分原因是與向後兼容。 – 2013-05-12 13:20:44

回答

22

要實現clone方法,你只需要做:

public Object clone() throws CloneNotSupportedException { 
    return super.clone(); 
} 

你當然也可以自定義設置,更深的副本,如果需要的方法。

調用super.clone()幾乎是強制性的,因爲除非類是final且因此不能被覆蓋,否則clone()方法必須返回與調用它的對象相同的類的實例。因此,簡單地創建一個新實例並複製該狀態將適用於此類,但不適用於所有子類。而且,你並不總是能夠訪問超類中包含的所有狀態。

總之,您將Object的保護克隆方法設爲public。的第一件事情是,Object.clone()方法確實是(這不是真正的代碼,但是這方法做什麼):

if (!(this instanceof Cloneable)) { 
    throw new CloneNotSupportedException(); 
} 

所以,Cloneable只是一個標記接口,讓Object.clone()方法知道它調用時不得拋出異常。

這是Java中設計最爲糟糕的部分之一。通常,您應該更喜歡使用副本構造函數,而不是使用clone()

+0

好吧,我可以從你的答案中瞭解到,今天不推薦使用這個接口,它的唯一用處是:如果我想使用Object類的clone方法,那麼我應該實現它。在我的例子中(我看到這個實現的類)實現了一個更深層次的類的副本,所以在這種情況下是否有任何理由來實現這個接口? – 2013-05-12 13:30:26

+0

如果你想覆蓋和使用'Object.clone()'方法,你需要實現這個接口。如果你想以另一種方式執行副本,那麼只要做你想做的事情。 – 2013-05-12 13:38:56

+0

有亞,所以重寫Object.clone()迫使我使用這個接口。感謝您提供豐富的答案。 – 2013-05-12 13:41:52

1

它允許您編寫更通用的代碼。如果您有多個實現Cloneable接口的類,並且想將它們的實例作爲參數傳遞給方法,則不必創建與一個變量類型不同的多種方法,那麼可以使用Cloneable t。這與其他接口一樣。而且,與其他所有接口一樣,它有點多繼承。實現這些接口使您的代碼更清晰。