Cloneable 接口的目的是作為對象的一個 mixin 接口, 表明這樣的對象允許克隆.
遺憾的是,因為Object 對象的clone 方法是受保護的, 一個對象僅僅實現(xiàn)了Cloneable, 但能直接調(diào)用clone, 所以導(dǎo)致Cloneable 沒有成功達到目的.
如果一個類實現(xiàn)了Cloneable, Object 的 clone 方法就返回該對象的逐域拷貝, 否則就會拋出 CloneNotSupportException 異常.
Clone 方法的通用約定是非常弱的:
創(chuàng)建和返回該對象的一個拷貝,這個拷貝的精確含義取決于該對象的類. 通常情況下滿足,但是不強制要求一定要滿足:
x.clone() != x, x.clone().getClass() == x.getClass(), x.clone.equals(x)
對于實現(xiàn)了 Cloneable 的類, 我們總是期望它能提供一個功能適當(dāng)?shù)墓械腸lone的方法.
實際上, clone 方法就是另一個構(gòu)造器; 必須確保它不會傷害到原始的對象, 并確保正確地創(chuàng)建被克隆對象中的約束條件.
clone 架構(gòu)與引用可變對象的final域的正常使用是不兼容的.
簡而言之, 所有實現(xiàn)了 Cloneable 接口的類都應(yīng)該用一個公有的方法覆蓋 clone.
此公有的clone 方法首先調(diào)用 super.clone, 然后修正任何需要修正的域.一般情況下,這意味著要拷貝任何包含內(nèi)部"深層結(jié)構(gòu)"的可變對象, 并用指向新對象的引用來代替原來指向這些對象的引用. 如果該類只包含基本類型的域,或者指向不可變對象的引用,那么多半情況下是沒有域需要修正的.
另一個實現(xiàn)對象拷貝的好辦法就是提供一個拷貝構(gòu)造器,或拷貝工廠:
- 拷貝構(gòu)造器: public Yum( Yum yum)
- 拷貝工廠: public static Yum nerInstance(Yum yum)
拷貝構(gòu)造器和拷貝工廠,都比Cloneable/clone方法具有更多的優(yōu)勢:
- 不依賴于某一種有風(fēng)險的,語言之外的對象創(chuàng)建機制
- 不要求遵守尚未制定好的文檔規(guī)范
- 不會與final 域的正常使用發(fā)生沖突
- 不會拋出不必要的首檢異常
- 不需要進行類型轉(zhuǎn)換
Cloneable 具有很多的限制,所以其他的接口都不應(yīng)該擴展(extend)這個接口, 為了繼承而設(shè)計的類也不應(yīng)該實現(xiàn)(implement)這個接口.