Object对象具体解释(二)之clone
clone方法會返回該實例對象的一個副本,通常情況下x.clone() != x || x.clone().getClass() == x.getClass() || x.clone().equals(x)也為真。但不嚴格要求,我們能夠通過重寫該方法來覆蓋。
protected native Object clone() throws CloneNotSupportedException;能夠看到。clone是一個本地方法,可能會拋出CloneNotSupportedException異常,什么情況下會拋出呢?
/*** A class implements the <code>Cloneable</code> interface to* indicate to the {@link java.lang.Object#clone()} method that it* is legal for that method to make a* field-for-field copy of instances of that class.* <p>* Invoking Object's clone method on an instance that does not implement the* <code>Cloneable</code> interface results in the exception* <code>CloneNotSupportedException</code> being thrown.* <p>* By convention, classes that implement this interface should override* <tt>Object.clone</tt> (which is protected) with a public method.* See {@link java.lang.Object#clone()} for details on overriding this* method.* <p>* Note that this interface does <i>not</i> contain the <tt>clone</tt> method.* Therefore, it is not possible to clone an object merely by virtue of the* fact that it implements this interface. Even if the clone method is invoked* reflectively, there is no guarantee that it will succeed.** @author unascribed* @see java.lang.CloneNotSupportedException* @see java.lang.Object#clone()* @since JDK1.0*/ public interface Cloneable { }說明中寫到。假設該對象未實現Cloneable 接口。那么當實例調用clone方法時。就會拋出該異常。
以下看Object中對于clone方法的描寫敘述。
當中提到的重寫clone方法的幾個注意點
1. 數組視為自己主動實現了Cloneable接口;
2. 非數組類型,使用clone方法,須要實現Cloneable接口。否則會拋出異常;
3. 非數組類型,克隆時,會新創建一個該類型的實例,并將被克隆對象實例的狀態復制給新創建對象。而且這是一個淺克隆-(影子克隆——shallow copy),而不是deep copy;
4. 重寫clone方法時。首先首先首先須要調用父類的clone方法。
那么問題來了。什么是shallow copy?而deep copy又是什么?
上樣例:
public class Test {public static void main(String[] args) throws CloneNotSupportedException {People people = new People("zjh", '男', 21, new Cloth(COLOR.WHITE , "XXL")); People clone = (People) people.clone();System.out.println("people == clone : " + (people == clone));System.out.println("people.getCloth() == clone.getCloth() : "+ (people.getCloth() == clone.getCloth()));System.out.println("people.getAge() == clone.getAge() : "+(people.getAge() == clone.getAge()));System.out.println("people.getName() == clone.getName() : "+(people.getName() == clone.getName()));} } class People implements Cloneable{private String name;private char sex;private int age;private Cloth cloth;/** * {@inheritDoc}.*/@Overrideprotected Object clone() throws CloneNotSupportedException {// TODO Auto-generated method stubreturn super.clone();}...若干getter/setter方法} class Cloth{private COLOR color;private String size;/*** 構造函數.* * @param color* @param size*/public Cloth(COLOR color, String size) {super();this.color = color;this.size = size;} enum COLOR {RED,WHITE,BLACK,GREEN,BLUE} }執行結果:
people == clone : false
people.getCloth() == clone.getCloth() : true
people.getSex() == clone.getSex() : true
people.getName() == clone.getName() : true
age,sex。name比較為真還能理解,為什么people.getCloth() == clone.getCloth() 也是true呢?又做了以下的測試。
people.getCloth().setColor(COLOR.BLACK);System.out.println(clone.getCloth().getColor());執行結果:
BLACK
如今已經能確定,people和它的克隆對象clone中的cloth引用指向了同一個Cloth實例。這就是“shallow copy”。那么想要“deep copy”。那么就須要在重寫方法的時候,同一時候調用對象屬性的克隆方法(要求該屬性對象也須要實現Cloneable)。
clone方法改動例如以下:
protected Object clone() throws CloneNotSupportedException {// TODO Auto-generated method stubPeople clone = (People) super.clone();clone.setCloth((Cloth)cloth.clone());return clone;}再執行上面的測試程序:
people == clone : false
people.getCloth() == clone.getCloth() : false
people.getAge() == clone.getAge() : true
people.getSex() == clone.getSex() : true
people.getName() == clone.getName() : true
總結
以上是生活随笔為你收集整理的Object对象具体解释(二)之clone的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅谈HashMap的实现原理
- 下一篇: Hyperledger fabric 1