程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java Object.clone()的效果

java Object.clone()的效果

編輯:關於JAVA

調用Object.clone()時,實際發生的是什麼事情呢?當我們在自己的類裡覆蓋clone()時,什麼東西對於super.clone()來說是最關鍵的呢?根類中的clone()方法負責建立正確的存儲容量,並通過“按位復制”將二進制位從原始對象中復制到新對象的存儲空間。也就是說,它並不只是預留存儲空間以及復制一個對象——實際需要調查出欲復制之對象的准確大小,然後復制那個對象。由於所有這些工作都是在由根類定義之clone()方法的內部代碼中進行的(根類並不知道要從自己這裡繼承出去什麼),所以大家或許已經猜到,這個過程需要用RTTI判斷欲克隆的對象的實際大小。采取這種方式,clone()方法便可建立起正確數量的存儲空間,並對那個類型進行正確的按位復制。
不管我們要做什麼,克隆過程的第一個部分通常都應該是調用super.clone()。通過進行一次准確的復制,這樣做可為後續的克隆進程建立起一個良好的基礎。隨後,可采取另一些必要的操作,以完成最終的克隆。
為確切了解其他操作是什麼,首先要正確理解Object.clone()為我們帶來了什麼。特別地,它會自動克隆所有句柄指向的目標嗎?下面這個例子可完成這種形式的檢測:
 

//: Snake.java
// Tests cloning to see if destination of
// handles are also cloned.

public class Snake implements Cloneable {
  private Snake next;
  private char c;
  // Value of i == number of segments
  Snake(int i, char x) {
    c = x;
    if(--i > 0)
      next = new Snake(i, (char)(x + 1));
  }
  void increment() {
    c++;
    if(next != null)
      next.increment();
  }
  public String toString() {
    String s = ":" + c;
    if(next != null)
      s += next.toString();
    return s;
  }
  public Object clone() {
    Object o = null;
    try {
      o = super.clone();
    } catch (CloneNotSupportedException e) {}
    return o;
  }
  public static void main(String[] args) {
    Snake s = new Snake(5, 'a');
    System.out.println("s = " + s);
    Snake s2 = (Snake)s.clone();
    System.out.println("s2 = " + s2);
    s.increment();
    System.out.println(
      "after s.increment, s2 = " + s2);
  }
} ///:~

一條Snake(蛇)由數段構成,每一段的類型都是Snake。所以,這是一個一段段鏈接起來的列表。所有段都是以循環方式創建的,每做好一段,都會使第一個構建器參數的值遞減,直至最終為零。而為給每段賦予一個獨一無二的標記,第二個參數(一個Char)的值在每次循環構建器調用時都會遞增。
increment()方法的作用是循環遞增每個標記,使我們能看到發生的變化;而toString則循環打印出每個標記。輸出如下:
 

s = :a:b:c:d:e
s2 = :a:b:c:d:e
after s.increment, s2 = :a:c:d:e:f

這意味著只有第一段才是由Object.clone()復制的,所以此時進行的是一種“淺層復制”。若希望復制整條蛇——即進行“深層復制”——必須在被覆蓋的clone()裡采取附加的操作。
通常可在從一個能克隆的類裡調用super.clone(),以確保所有基礎類行動(包括Object.clone())能夠進行。隨著是為對象內每個句柄都明確調用一個clone();否則那些句柄會別名變成原始對象的句柄。構建器的調用也大致相同——首先構造基礎類,然後是下一個衍生的構建器……以此類推,直到位於最深層的衍生構建器。區別在於clone()並不是個構建器,所以沒有辦法實現自動克隆。為了克隆,必須由自己明確進行。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved