NewMoring

          與Java同路,贏在未來。

          統計

          積分與排名

          http://bbs.javawind.net/index.jspx

          http://www.chubeibao.com/bbs/index.php

          http://www.java2000.net/

          http://www.javaeye.com/

          http://www.javathinker.org/index.jsp

          http://www.programbbs.com/bbs/index.asp

          最新評論

          java Serializable 類 序列化1《轉帖》

          1.5 定義類的可序列化域
          可用兩種不同的方式來定義類的可序列化域。類的可序列化域被缺省定義為非瞬態和非靜態域。 通過在 Serializable 類中聲明一個指定的域 serialPersistentFields,即可覆蓋該缺省值。 該域的初始化必須用 ObjectStreamField 對象的數組來完成,該對象列出了可序列化域的名稱和類型。該域的修飾符應為 private、static 和 final。
          例如,以下聲明將復制缺省行為。
          class List implements Serializable {
              List next;
              private static final ObjectStreamField[] serialPersistentFields
                           = {new ObjectStreamField("next", List.class)};

          }
          用 serialPersistentFields 為某個類定義可序列化域后,即無需再將可序列化域限制在當前 Serializable 類的定義之內。利用第 1.7 節,"訪問類的可序列化域" 中描述的接口,Serializable 類的 writeObject 和 readObject 方法可將該類的當前實現映射到其可序列化域。因此,后續版本中可以改變 Serializable 類的域,但前提是保持與版本兼容的 Serializable 域的映射。

          1.6 對類的可序列化域和數據存檔
          對類的可序列化狀態進行存檔以使其與 Serializable 類的其它實現間可互操作,或者對類演變進行存檔,這些都非常必要。對可序列化域進行存檔可幫助用戶最終確定該域是否應序列化。 序列化 javadoc 標記 @serial、@serialField 和 @serialData 可提供對源代碼中 Serializable 類的序列化形式進行存檔的方法。

          對于缺省的可序列化域,@serial 標記應放在 javadoc 注釋中。語法如下:@serial field-description 其中可選項 field-description 描述域及其容許值的含義。 field-description 可跨多行。當初始版本中增加一個域時,@since 標記指出所添域的版本。@serial 的 field-description 提供針對序列化的文檔。在序列化形式文檔內,field-description 將被添加到 javadoc 注釋中。
          @serialField 標記用于對 serialPersistentFields 數組的 ObjectStreamField 組件進行存檔。每個 ObjectStreamField 組件都應使用其中的一個標記。語法如下:@serialField field-name field-type field-description
          @serialData 標記描述寫入或讀取數據的次序和類型。該標記描述 writeObject 所寫入的可選數據或 Externalizable.writeExternal 方法所寫入的所有數據的次序或類型。語法如下:@serialData data-description
          javadoc 應用程序識別序列化 javadoc 標記并為每個 Serializable 和 Externalizable 類生成說明文字。有關這些標記用法的示例,參見第 C.1 節 "java.io.File 可替代實現的示例。"

          當某個類被聲明為 Serializable 時,即通過可序列化域及可選數據(按名稱和類型)定義了該對象的可序列化狀態。可選數據只能用 Serializable 類中的 writeObject 方法顯式寫入,而其讀取則可通過 Serializable 類和 readObject 方法進行。否則,序列化將跳過無法讀取的可選數據。

          當一個類被聲明為 Externalizable 時,通過類自身寫入流的數據即定義了該類的序列化狀態。 該類必須指定順序、類型及寫入流的每個數據的含義。同時還必須處理其自身的演變,從而可讀取以前版本所寫入的數據,或寫入以前版本所能讀取的數據。在存儲和恢復數據時,該類必須與父類相一致。必須指定流中父類數據的位置。

          類的設計者必須確保為類存儲的信息對于持久性是合適的,而且遵循為實現序列化的互操作性和演變而指定的序列化規則。第 5 章“可序列化對象的版本演變”對類的演變進行了更詳細的說明。

          1.10 Serializable 接口
          Serialization 對象生成流,其中提供有關所存對象的 JavaTM 類的信息。對于可序列化對象,即使存在該類的不同(但兼容)版本的實現,也要保持足夠的信息以恢復這些對象。定義 Serializable 接口可以標識實現可序列化協議的類:


          package java.io;

          public interface Serializable {};

          Serializable 類必須具備如下功能:

          實現 java.io.Serializable 接口
          標識應序列化的域
          (使用 serialPersistentFields 成員以顯式聲明其可序列化,或者使用瞬態關鍵字來指示非序列域。)
          可訪問其第一個非序列化父類的無參數構造函數。
          該類可根據需要定義如下方法:

          writeObject 方法,用于控制要保存哪些信息或將附加信息添加到流中
          readObject 方法,用于讀取由相應 writeObject 方法寫入的信息,或在對象恢復后更新其狀態
          writeReplace 方法,用于允許類指定寫入流的替換對象
          readResolve 方法,用于允許類為剛從流中讀取的對象指定替換對象
          ObjectOutputStream 和 ObjectInputStream 支持所操作的可序列化類的演變(允許類發生改變以兼容早期版本的類)。有關實現兼容變化的機制的信息,參見第 5.5 節“兼容的 JavaTM 類型演變”。
          --------------------------------------------------------------------------
          class ObjectYouWannaSave implements Serializable{
             int x; int y;
             SubObject so = new SubObject();
             ..........
          }

          class SubObject implements Serializable{
             String s = "abc"; //String is OK, because String is java.io.Serializable
          }

          public class Save{ // in Save.java
             public void main(String[] args) {
                ObjectYouWannaSave original = new ObjectYouWannaSave();
                original.x = -1; original.y = 100; .....
               
                ObjectOutputStream out = null;
                try{
                  out = new ObjectOutputStream(new FileOutputStream(new File("c:/save.dat")));
                  out.writeObject(original);
                }catch(Exceptione){
                }finally{
                  try{out.close();}catch(Exception e){}
                }
             }
          }

          public class Read{ // in Read.java
             public void main(String[] args) {
                ObjectInputStream in = null;
                try{
                  out = new ObjectInStream(new FileInStream(new File("c:/save.dat")));
                  ObjectYouWannaSave o = (ObjectYouWannaSave)in.readObject();
                  System.out.println("x="+o.x);
                  System.out.println("subobject.string=" + o.so.s);
                  ........
                }catch(Exceptione){
                }finally{
                  try{in.close();}catch(Exception e){}
                }
             }
          }

          這是個最簡單的例子,先運行Save,以后什么時候運行Read都可以(只要c:\save.dat文件還存在就可以了)
          --------------------------------------------------
          對象的壽命通常隨著生成該對象的程序終止而終止,有時候,可能需要將對象的狀態保存下來,在需要的時候
          再將對象恢復,我們把對象的這種記錄自己狀態的以便將來再生的能力,叫做對象的持續性(PERSISTENCE),
          對象通過寫出描述自己狀態的數值來記錄自己,這個過程叫對象的串行化Serializable。串行化的主要任務是寫
          出對象實例變量的值。如果變量是另一個對象的引用,則引用的對象也要串行化,這是個遞歸過程。
          --------------------------------------------------------------------
          java.io.Serializable interface是一個較為特殊的接口:
          The serialization interface has no methods or fields and serves
          only to identify the semantics of being serializable
          即:它主要是一個用于通知JVM的標志

          class X implements java.io.Serializable{...}

          如果你要定制你自己的serializable行為,你應該在X中實現以下2個方法:
           private void writeObject(java.io.ObjectOutputStream out)
               throws IOException
           private void readObject(java.io.ObjectInputStream in)
               throws IOException, ClassNotFoundException;

          否則將按缺省的策略進行。

          由于上述2個方法是private的,所以在某些情況下,可以使用
          java.io.Serializable的子接口java.io.Externalizable,
          在這個interface中有2個public方法:

          public void writeExternal(ObjectOutput out)
                             throws IOException

          public void readExternal(ObjectInput in)
                            throws IOException,
                                   ClassNotFoundException


          ----------------------------------------------------------------------------
          Serializable是一個串行化接口,它沒有任何的屬性和方法,一個類實現了串行化接口,就表明
          該類具有持久性,通過WriteObjcet可將其持久保存在磁盤,在需要時,可用ReadObject從磁盤中讀出,次時,對象的狀態和存入似的相同。上面給出的列子比較簡單,可通過串行化保存一個
          鏈表對象,它的每個節點數據也會被保存。 當然,串行化接口還有其他用途,例如HTTP隧道等

          -----------------------------------------------------------------------
          對象序列化的持續性要和永久對象分別開。序列化只能達到有線持續性
          在同一個jvm上可以重構對象的內容,達到持續性
          ---------------------------------------------------------------------
          java序列化主要是用于兩個方面:
          一個是java的RMI(遠程方法調用-Remote method invocation),你可以使用別人機器上的對象就像在你自己的機器上使用它一樣(通過序列化),另外,在使用javabean時也需要使用序列化,序列化主要就是使用在這兩方面。
          -------------------------------------------------------------
          所謂序列化就是把把對象以一個代碼串的形式表示出來,
          這樣可以保存到磁盤或則通過網絡傳輸,接受方可以在把代碼串恢復成對象
          具體的串形化方法可以自己寫,接收放就可以根據您串形的規則把對象恢復出來
          --------------------------------------------------------------------
          序列化是把一個對象的狀態寫入一個字節流的過程,它執行RMI,RMI允許一臺機器上的JAVA對象調用不同機器上的JAVA對象方法,對象可以作為參數提供給那個遠程方法,發送機序列化該對象并傳送它,接收機執行反序列化。
          序列化和反序列化的關系圖表可形成包含循環引用的順序圖表。這是整個序列化的總體思想。
          而Serializable接口屬于支持序列化的一個接口,只有一個實現它的對象可以被序列化工具存儲和回復,Serializable接口沒有定義任何成員,只用來表示一個累可以被序列化,若該類可以序列化,那么它的所有子類都可以。
          下面是關于序列化的一個實例:
          [b:a55efb5f91]程序名稱:SerializationDemo.java
          程序主題:實現對象的序列化和反序列化
          程序說明:該程序由實例化一個MyClass類的對象開始,該對象有三個實例變量,類型分別為String、int、double,是希望存儲和恢復的信息。[/b:a55efb5f91]

          [code:1:a55efb5f91]

          import java.io.*;

          public class SerializationDemo{
                  public static void main(String args[]){

          //Object serialization
          try{
          MyClass object1=new MyClass("Hello",-7,2.7e10);
          System.out.println("object1:"+object1);
          FileOutputStream fos=new FileOutputStream("serial");
          ObjectOutputStream oos=new ObjectOutputStream(fos);
          oos.writeObject(object1);
          oos.flush();
          oos.close();
          }
          catch(Exception e){
          System.out.println("Exception during serialization:"+e);
          System.exit(0);
          }

          //Object deserialization
          try{
          MyClass object2;
          FileInputStream fis=new FileInputStream("serial");
          ObjectInputStream ois=new ObjectInputStream(fis);
          object2=(MyClass)ois.readObject();
          ois.close();
          System.out.println("object2:"+object2);
          }
          catch(Exception e){
          System.out.println("Exception during deserialization:"+e);
          System.exit(0);
          }
          }
          }

          class MyClass implements Serializable{
          String s;
          int i;
          double d;
          public MyClass(String s,int i,double d){
          this.s=s;
          this.i=i;
          this.d=d;
          }
          public String toString(){
          return "s="+s+";i="+i+";d="+d;
          }
          }
          [/code:1:a55efb5f91]

          程序運行結果:object1和object2的實例變量是一樣的,輸出如下:[code:1:a55efb5f91]object1:s=Hello;i=-7;d=2.7E10
          object2:s=Hello;i=-7;d=2.7E10[/code:1:a55efb5f91]
          --------------------------------------------------------------------------------
          Object serialization的定義:
          Object serialization 允許你將實現了Serializable接口的對象轉換為字節序列,這些字節序列可以被完全存儲以備以后重新生成原來的對象。 

          serialization不但可以在本機做,而且可以經由網絡操作(就是貓小說的RMI)。這個好處是很大的----因為它自動屏蔽了操作系統的差異,字節順序(用Unix下的c開發過網絡編程的人應該知道這個概念,我就容易在這上面犯錯)等。比如,在Window平臺生成一個對象并序列化之,然后通過網絡傳到一臺Unix機器上,然后可以在這臺Unix機器上正確地重構這個對象。


          Object serialization主要用來支持2種主要的特性:
          1。Java的RMI(remote method invocation).RMI允許象在本機上一樣操作遠程機器上的對象。當發送消息給遠程對象時,就需要用到serializaiton機制來發送參數和接收返回直。

          2。Java的JavaBeans.   Bean的狀態信息通常是在設計時配置的。Bean的狀態信息必須被存起來,以便當程序運行時能恢復這些狀態信息。這也需要serializaiton機制。

           

          二。持久化
          持久化應該是英文里的persistence.但是Java語言里現在只支持lightweight persistence,就是輕量級持久化,這是通過serialization機制來實現的。

          persistence是指一個對象的生命周期不由程序是否執行來決定,即使是在程序終止時這個對象也存在。它把一個serializable的對象寫到磁盤(本機或其他機器上的非RAM存儲器),并在程序重新調用時再讀取對象到通常的RAM存儲器。

          為什么說Java的serialization機制實現的是lightweight persistence?因為你必須顯式的序列化和反序列化程序里的對象;而不是直接由一個關鍵詞來定義一個對象是序列化的然后由系統做相應的處理。  如果以后的Java版本出現一個新的關鍵字來實現這種機制,比如就是persistence,如果我用

          persistence  (String s="chinaunix")

          然后系統自動做上面程序里的那些處理,那么Java就實現了persistence.

          posted on 2009-05-27 14:16 清晨 閱讀(758) 評論(0)  編輯  收藏 所屬分類: java語言的相關問題

          主站蜘蛛池模板: 临沭县| 博爱县| 通州区| 沈丘县| 彩票| 双流县| 韩城市| 上蔡县| 荆州市| 四川省| 黔江区| 涟源市| 商水县| 合江县| 荆州市| 中山市| 和林格尔县| 孟津县| 龙门县| 昌平区| 华容县| 临西县| 始兴县| 云林县| 汉川市| 昌江| 舒城县| 定结县| 晋江市| 静宁县| 图们市| 高台县| 景东| 平陆县| 二连浩特市| 乐业县| 汝城县| 临颍县| 金门县| 无锡市| 泽州县|