發新話題

Java 教程《語法說明》Object Initialization Mechanisms

Java 教程《語法說明》Object Initialization Mechanisms

■ Object Initialization Mechanisms
除了 new 運算子外,Java 另外提供 3 種機制建立 object:
1. 呼叫某個 object 的 clone( ) 方法(在 java.lang.Object 類別)
2. Deserializing 某個 object
3. 使用 java.lang.Class 中的 newInstance( ) 方法。

● clone( ) method
Java 要拷貝某個 object,可利用該物件的 clone( ) 方法。呼叫 clone( ) 會引發下列其中之一的事件:
1. 傳回指向該複製成功物件的參考值
2. 丟出 CloneNotSupportedException 例外

clone( ) 是類別 Object 中的 method會被所有的物件繼承,任何物件呼叫 clone( ) 會產生下列情況:
若該類別不實作( implement) Cloneable 介面,則呼叫 clone( ) 丟出 CloneNotSupportedException 例外;否則複製該物件並依據所給的程式碼指定初始值,並且傳回指向此一複製成功的新物件的參考值。

1. Cloneable 介面中不包含任何 member 的空介面,該介面僅止於指明某類別是否支援 clone method。
 要複製某類別的物件,該物件所屬的類別或其父類別必須實作 Cloneable 介面。
2. 在 Object 類別中的 clone( ) method 宣告為 protected,所以只有同一package中的 subclasses 和 members 可以呼叫某物件的 clone( );除非override 該method 並宣告其為 public 讓不同 package 中的 class 皆可呼叫存取此 clone( ) method。
3. clone的副作用
 複製一個物件時,若是該物件有參照到其它的物件,則被複製的新物件還是會參照到同一個物件。若是新物件對於該參照物件做了改變,則舊物件也是參照到這個被改變的物件。

[範例]
public class ShallowCloneTest {
  public ShallowCloneTest( ) throws java.lang.CloneNotSupportedException {
    MyEmployee objEp1 = new MyEmployee("Joe","22");
    MyEmployee objEp2 = (MyEmployee)objEp1.clone( );
    objEp2.name="new name";
    System.out.println(objEp1.name);
  } 
  public static void main(String args[ ]) throws java.lang.CloneNotSupportedException {
    new ShallowCloneTest( );  // 顯示「new name」,both objEp1 and objEp2 MyEmployee instances are the same
  }
}
class MyEmployee implements Cloneable {
  public String name;
  public String age;
  public Employee(String name, String age) {
    this.name = name;
    this.age = age;
  }
  public Object clone( ) throws java.lang.CloneNotSupportedException {
    return this;
  }
}


● 程式執行時有六個地方可以存放object資料、管理記憶體佈局(參見 Bruce Eckel, Thinking in Java -3rd):
1. 暫存器(Registers)。
 速度最快的儲存區域,位於處理器內部。不過由於暫存器個數有限,所以由編譯器加以分配。程式設計時對於暫存器並沒有直接的控制權,也沒辦法在程式裡頭找到暫存器任何存在的跡象。
2. Stack(堆疊)。
 位於一般的RAM(random-access memory,隨機存取記憶體)。經由堆禳U指標(stack pointer)提供直接支援。
 當程式配置一塊新的記憶體時,stack 指標便往後移;釋放記憶體時,指標則往前移回。這種方式不僅很快,效率也高,速度僅次於暫存器。Java 編譯器必須能夠完全掌握它所編譯的程式中「存在stack裏的所有資料的實際大小和存活時間」,才可以產生「將stack 指標前後移動」的程式碼。但如此一來限製程式的彈性,所以儘管某 Java 的儲存空間(storage)是在stack 內,特別是 object reference,但卻不將 object 也置於 stack 內。
3. Heap(堆積)。
 Heap 是一種通用性質的記憶體儲存空間(也存在於RAM中),用來置放所有的Java objects。Heap 勝過stack 之處在於,編譯器不需知道需從 heap 中配置多少空間,也不需知道在 heap 配置的空間究竟需要存在多久。因此自 heap 配置儲存空間可以獲得高度的彈性。每當要產生objects,只需在程式碼中使用 new,執行時便自 heap 配置空間。而此種彈性付出的代價是:從heap中配置空間,較從stack中配置空間所耗費的時間還長(假設你真的可以在Java 中像C++一樣自 stack 產生object 的話)。
4. 靜態儲存空間(Static storage)。
 這裡使用「靜態」一詞,指的是「在固定位置上(in a fixed location)」(也在RAM裏頭)。靜態儲存空間存放著「程式執行期間」一直存在的資料。你可以使用關鍵字static,將某個 object 內的特定成員設為靜態,但在Java中 object 本身永遠都不置於靜態儲存空間(static storage)中。
5. 常數儲存空間(Constant storage)。
 常數值因不改變,常常被直接置於程式碼內,這是一個安全的作法。在 embedded system 中,有時候常數和外界隔離開來,所以也可以放到唯讀記憶體(read-only memory,ROM)中。
6. 非RAM儲存空間(Non-RAM storage)。
 如果資料完全存活於程式之外,即使程式不執行,資料也能夠繼續存在,脫離程式的控制。最主要的 2 個例子便是 streamedobjects(串流化物件)和persistent objects(永續性物件)。
 在streamed objects 的形式中,objects 被轉換為一連串的 bytes(streams of bytes),這些 bytes 通常用來傳送到另一部機器。在 persistent objects 的形式中,objects 被儲存於磁碟,所以即使程式結束了,這些 objects 的狀態還能夠繼續保有。此類儲存空間的特點在於,它們能夠將 objects 轉換為可儲存於其他媒介的形式,並在必要的時候將所儲存的資料還原成可儲存於RAM中的一般objects。Java 提供了所謂「輕量級的永續性(lightweight persistence)」,新的版本有可能提供 persistence object 更完善的解決方案。

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。