一、Cloneable 接口的目的是代表對象時複製的數組
二、Object 的克隆方法是受保護的安全
- 不借助於反射,僅僅實現Cloneable 接口是沒法調用clone 方法的
-
三、Cloneable 接口決定了,Object 中受保護的clone方法實現的行爲架構
- 若是實現了Cloneable,Object 的clone 方法返回逐域拷貝
- 不然,拋出CloneNotSupportedException 異常
- 接口的極端非典型用法,不值得效仿
- 一般狀況下,實現接口是爲了代表它能夠爲類作些什麼
- Cloneable 接口改變了超類中受保護的方法的行爲
- 實現了該接口,無需調用構造器就能夠建立對象
四、clone方法的通用約定很是弱ide
- 拷貝的精確含義取決於,實現類自己
- 通常意義上(但不是絕對):
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
五、不調用構造器的規定太強硬this
- 行爲良好的構造器能夠由構造器建立,再複製內部對象
- 若是是final 類,甚至能夠是返回一個構造器建立的對象
六、x.clone().getClass()==x.getClass() 一般狀況下是true 線程
- 在子類中調用super.clone(),返回的是子類的實例
- 超類實現這種功能的惟一途徑是返回一個super.clone()返回的對象
- 全部超類都遵照該規則,最後返回Object 的clone ,返回一個正確的實例(行爲良好clone 方法)
- 若是返回一個構造器建立的類,就獲得一個錯誤的實例
七、Object 的clone 方法是一個本地方法設計
- Object 的clone 方法是一個本地方法
- 執行的時候使用RTTI(run-time type identification)
- 動態獲得正在調用clone方法的那個reference
- 根據它的大小申請內存空間,而後進行bitwise的複製
- 將該對象的內存空間徹底複製到新的空間中去,從而達到shallowcopy的目的
- 獲得當前類的副本,不是父類
- 根本沒有必用調用this.clone()
八、從超類的角度,拷貝對象是對原始對象功能的完整拷貝對象
- 基本類型和不可變類,返回對象沒有問題,不須要進一步處理
![](http://static.javashuo.com/static/loading.gif)
永遠不要讓客戶去作類庫能夠提供的事情繼承
- 若是帶有可變類,簡單的clone 實現可能帶來災難性後果
- 下述Stack 類,若是採用簡單的clone ,elements僅僅是引用複製,新老引用指向同一個數組
![](http://static.javashuo.com/static/loading.gif)
clone 方法是類的另外一個構造器,確保不要傷害原有對象,確保正確建立被克隆對象全部約束條件遞歸
![](http://static.javashuo.com/static/loading.gif)
數組不須要 類型轉換,類型在編譯時與被克隆類型是相同的
九、若是可變類存在final 的域,上述方案不能正常運行:clone 方法會被禁止賦新值
- clone 架構與引用可變對象的final 域之間自己就是衝突的
- 去掉final 再clone
十、遞歸調用clone 有時還不夠
![](http://static.javashuo.com/static/loading.gif)
- 上述類,帶有內部類,須要複製每個對象(深度拷貝):
- 遞歸調用式拷貝:
![](http://static.javashuo.com/static/loading.gif)
- 遞歸調用針對鏈表中每一個元素,都消耗一段棧空間
- 鏈表過長可能會溢出
- 迭代式拷貝避免了上述狀況(迭代器能用就用啊):
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
十一、克隆複雜對象的最後一種方法
- 先調用super.clone 方法
- 把全部域置空
- 最後再把每一個值都填進去
- 這是一種簡單、優美、合理的克隆方法
- 運行效率比直接操做對象內部狀態要差
十二、clone 方法與構造器同樣,clone 方法在構造過程當中,不能調用新對象任何非 final 的方法
- 新對象被拷貝出來前,不能調用它的非 final 方法
1三、覆蓋版本的clone 方法不該該忽略聲明可拋出異常 CloneNotSupportedException
- Object 的clone 方法可拋出 CloneNotSupportedException 異常
- 公有的覆蓋版本clone 方法可省略
- 省略後使用更輕鬆
1四、專門爲繼承而設計的類<17條>,應儘可能模仿Object 的clone 方法
- (protected、可拋出上述異常)
- 不該該實現Cloneable 接口,繼承類可自由選擇是否實現Cloneable 接口
- 這樣便直接擴展了Object
1五、線程安全的類實現 Cloneable 接口,clone 方法也必須同步
- Object 的clone 沒有同步
- 使用同步的clone 方法調用super.clone()
1六、不可變類不要提供拷貝方法
1七、拷貝構造器(拷貝工廠)
![](http://static.javashuo.com/static/loading.gif)
優點:
- 不依賴於有風險的、對象以外的對象建立機制
- 不要求遵照還沒有指定好的文檔規範
- 不會與 final 域的正常使用發生衝突
- 不會拋出沒必要要的受檢異常
- 不須要進行類型轉換
- 採用拷貝構造器沒有放棄接口的功能特性(Cloneable 接口是一個空接口)
1八、拷貝構造器(拷貝工廠)能夠帶有一個參數:
- 參數類型是經過該類實現的接口
- 實質就是轉換構造器(轉換工廠)
- 好比HashSet 轉換成TreeSet:new TreeSet(s)