一個普通的Java類,繼承了Object對象,便繼承了該對象的Clone方法
protected native Object clone() throws CloneNotSupportedException;
但是Java基礎類或String類卻不支持這樣的操作
Integer x = new Integer(10);
x.clone(); //編譯報錯
String s = "abc";
s.clone(); //編譯報錯
可理解爲,Integer類或者String類直接雖然繼承了Object,在Integer或者String內部使可以訪問clone方法的,由於該方法是protected限制級別。
Java對象Clone對象
1.實現Cloneable接口。該接口標記類爲可克隆的,Object.clone()方法會驗證一個類是否實現了Cloneable接口,如果沒有,在運行期會throw CloneNotSupportedException。
2.可覆蓋clone方法,實現語境下的淺層複製或者深層複製。
3.調用super.clone()方法。
一個簡單的例子實現淺層複製
package clone;
/**
* 克隆研究
*
* @author xl
*
*/
public class Snake implements Cloneable {
Snake next;
char c;
// 構造器
public Snake(int i, char x) {
this.c = x;
if (--i > 0) {
next = new Snake(i, (char) (x + 1));
}
}
// 增量
public void increment() {
c++;
if (next != null) {
next.increment();
}
}
@Override
public String toString() {
String s = ":" + c;
if (next != null) {
s += next.toString();
}
return s;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws CloneNotSupportedException {
Snake s = new Snake(5, 'a');
System.out.println("s = " + s);
Snake s2 = (Snake) s.clone();
System.out.println("s2 = " + s2);
System.out.println("s = " + s.next.hashCode() + ": " + s.c);
System.out.println("s2 = " + s2.next.hashCode() + ": " + s2.c);
//s2.increment();
System.out.println("after s.increment, s2 = " + s2);
}
}
再次重載clone,可實現深層複製
@Override
protected Object clone() throws CloneNotSupportedException {
Snake s = null;
s = (Snake) super.clone();
if (s.next != null)
s.next = (Snake) s.next.clone();
return s;
}
克隆原理
Object.clone()方法負責建立正確的存儲容量(原對象的大小),並通過“按位複製”將二進制位從原始對象中複製到新對象的存儲空間。所以克隆的第一步應該調用super.clone()方法,爲後續的複製建立基礎,最後在自己的重載方法中完成必要的操作,以最終完成克隆。