為什么要克隆
首先思考一個問題, 為什么需要克隆對象? 直接new一個對象不行嗎?
克隆的對象可能包含一些已經修改過的屬性, 而new出來的對象的屬性都還是初始化時候的值, 所以當需要一個新的對象來保存當前對象的"狀態"時就要靠克隆了.
當然, 把對象的屬性一個一個的賦值給新new的對象也是可以的, 但是這樣一來麻煩不說, 二來, 我們通過源碼查看 Object的clone方法是一個native方法(native方法是非Java語言實現的代碼, 供Java程序調用, 要想訪問比較底層的與操作系統相關的就沒辦法了, 只能由靠近操作系統的語言來實現), 就是快啊, 實在更底層實現的.
我們常見的 Object a = new Object(); Object b; b = a; 這種形式的代碼復制的是引用, 即對象在內存中的地址, a和b指向了同一個對象. 而通過clone方法賦值的對象跟原來的對象是同時獨立存在的.
概念
淺克隆:
被克隆的對象里的所有變量值都與原來的對象相同, 而所有對其他對象的引用仍然指向原來的對象. 簡單說, 淺克隆僅克隆當前對象, 而不克隆當前對象所引用的對象.
深克隆:
被克隆的對象里的所有變量值都與原來的對象相同, 那些引用其他對象的變量將指向被復制過的新對象, 而不再是原來被引用的對象. 簡單說, 深克隆不僅克隆了當前對象, 還把當前對象所引用的對象都復制了一遍.
Object中的clone
Object類中的clone()方法屬於淺克隆. 它的工作原理如下: 在內存中先開辟一塊和原始對象相同的空間, 然后復制原始對象的內容. 對於基本數據類型, 這樣操作當然沒問題, 但對於引用類型, 由於保存的僅僅是對象的引用, 克隆過去的引用所指向的是同一個對象.
Java中實現淺克隆
java中實現clone要實現 Cloneable 接口, 該接口十分簡單, 源碼如下:

僅僅起到一個標識的作用.
下面是一個實現淺克隆的例子:

可以看到, 對象確實不是原來的對象了, 但是其中的引用對象卻還是原來的對象.
淺克隆對於引用對象僅拷貝引用.
如果一個對象只包含原始數據或者不可變對象域(如: String), 推薦使用淺克隆.
Java中實現深克隆
將類中的所有引用類型都進行clone, 並重寫對象clone()方法, 對所有引用類型進行clone.
代碼如下:

將所有引用類型都進行clone, 實現了深克隆.
Java序列化克隆
如果引用類型中海包括引用類型, 要實現多層克隆會很麻煩, 這使用可以使用序列化和反序列化的方式實現對象的深克隆.
把對象寫到字節流中的過程是序列化的過程, 而把對象從字節流中讀出來的過程是反序列化的過程. 由於Java序列化的過程中, 寫在流中的是對象的一個拷貝, 而原對象仍然在JVM中, 所以可以利用這個原理來實現對對象的深克隆.
上面代碼使用序列化實現如下:

可以將序列化克隆封裝為一個方法, 如下所示:

通過該工具類即可進行深度克隆. 要是用該方法, 對象、對象的所有引用類型、引用類型中的引用類型都要實現 Serializable 接口.
當然, 對象中的final對象是不能進行clone的, 因為final的限制.
如果用線程安全的類實現Cloneable, 要保證它的clone方法做好同步工作, 默認的Object.clone方法是沒有同步的.