亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

java.io.Serializable淺析

系統 1814 0

java.io.Serializable淺析

?

Java API中java.io.Serializable接口源碼:

        
          
            1
          
          
            public
          
          
            interface
          
          
             Serializable { 
          
          
            2
          
           }
        
      

  類通過實現java.io.Serializable接口可以啟用其序列化功能。未實現次接口的類無法使其任何狀態序列化或反序列化。可序列化類的所有子類型本身都是可序列化的。序列化接口沒有方法或字段,僅用于標識可序列化的語義。

  Java的"對象序列化"能讓你將一個實現了Serializable接口的對象轉換成byte流,這樣日后要用這個對象時候,你就能把這些byte數據恢復出來,并據此重新構建那個對象了。

  要想序列化對象,你必須先創建一個OutputStream,然后把它嵌進ObjectOutputStream。這時,你就能用writeObject()方法把對象寫入OutputStream了。

  writeObject()方法負責寫入特定類的對象的狀態,以便相應的 readObject()方法可以還原它。通過調用 out.defaultWriteObject 可以調用保存 Object 的字段的默認機制。該方法本身不需要涉及屬于其超類或子類的狀態。狀態是通過使用 writeObject 方法或使用 DataOutput 支持的用于基本數據類型的方法將各個字段寫入 ObjectOutputStream 來保存的。

  讀的時候,你得把InputStream嵌到ObjectInputStream里面,然后再調用readObject()方法。不過這樣讀出來的,只是一個Object的reference,因此在用之前,還得先下傳。readObject() 方法負責從流中讀取并還原類字段。它可以調用 in.defaultReadObject 來調用默認機制,以還原對象的非靜態和非瞬態字段。  defaultReadObject()方法使用流中的信息來分配流中通過當前對象中相應命名字段保存的對象的字段。這用于處理類發展后需要添加新字段的情形。該方法本身不需要涉及屬于其超類或子類的狀態。狀態是通過使用 writeObject 方法或使用 DataOutput 支持的用于基本數據類型的方法將各個字段寫入 ObjectOutputStream 來保存的。

  在序列化時,有幾點要注意的:

  1: 當一個對象被序列化時,只保存對象的非靜態成員變量(包括聲明為private的變量),不能保存任何的成員方法和靜態的成員變量。

  2:如果一個對象的成員變量是一個對象,那么這個對象的數據成員也會被序列化。

  3:如果一個可序列化的對象包含對某個不可序列化的對象的引用,那么整個序列化操作將會失敗,并且會拋出一個NotSerializableException。我們可以將這個引用標記為transient,那么對象仍然可以序列化。

?

  1、序列化是干什么的?

  簡單說就是為了 保存在內存中的各種對象的狀態 ,并且可以把保存的對象狀態再讀出來。雖然你可以用你自己的各種各樣的方法來保存Object States,但是Java給你提供一種應該比你自己好的保存對象狀態的機制,那就是序列化。

  2、什么情況下需要序列化

  a)當你想把的內存中的對象保存到一個文件中或者數據庫中時候;
  b)當你想用套接字在網絡上傳送對象的時候;
  c)當你想通過RMI傳輸對象的時候;

  3、當對一個對象實現序列化時,究竟發生了什么?

  在沒有序列化前,每個保存在堆(Heap)中的對象都有相應的狀態(state),即實例變量(instance ariable)比如:

        
          
            1
          
           Foo myFoo = 
          
            new
          
          
             Foo(); 
          
          
            2
          
           myFoo .setWidth(37
          
            ); 
          
          
            3
          
           myFoo.setHeight(70);
        
      

  當通過下面的代碼序列化之后,MyFoo對象中的width和Height實例變量的值(37,70)都被保存到foo.ser文件中,這樣以后又可以把它從文件中讀出來,重新在堆中創建原來的對象。當然保存時候不僅僅是保存對象的實例變量的值,JVM還要保存一些小量信息,比如類的類型等以便恢復原來的對象。

        
          
            1
          
           FileOutputStream fs = 
          
            new
          
           FileOutputStream("foo.ser"
          
            ); 
          
          
            2
          
           ObjectOutputStream os = 
          
            new
          
          
             ObjectOutputStream(fs); 
          
          
            3
          
           os.writeObject(myFoo);
        
      

  4、實現序列化(保存到一個文件)的步驟

a)Make a FileOutputStream

  java 代碼
  FileOutputStream fs = new FileOutputStream("foo.ser");

b)Make a ObjectOutputStream

  java 代碼
  ObjectOutputStream os = new ObjectOutputStream(fs);

c)write the object

  java 代碼
  os.writeObject(myObject1);
  os.writeObject(myObject2);
  os.writeObject(myObject3);

d) close the ObjectOutputStream

  java 代碼
  os.close();

  5、舉例說明

?

        
          
             1
          
          
            public
          
          
            class
          
           Box 
          
            implements
          
          
             Serializable { 
          
          
             2
          
          
            private
          
          
            static
          
          
            final
          
          
            long
          
           serialVersionUID = -3450064362986273896L
          
            ; 
          
          
             3
          
          
             4
          
          
            private
          
          
            int
          
          
             width; 
          
          
             5
          
          
            private
          
          
            int
          
          
             height; 
          
          
             6
          
          
             7
          
          
            public
          
          
            static
          
          
            void
          
          
             main(String[] args) { 
          
          
             8
          
                   Box myBox=
          
            new
          
          
             Box(); 
          
          
             9
          
                   myBox.setWidth(50
          
            ); 
          
          
            10
          
                   myBox.setHeight(30
          
            ); 
          
          
            11
          
          
            try
          
          
             { 
          
          
            12
          
                       FileOutputStream fs=
          
            new
          
           FileOutputStream("F:\\foo.ser"
          
            ); 
          
          
            13
          
                       ObjectOutputStream os=
          
            new
          
          
             ObjectOutputStream(fs); 
          
          
            14
          
          
             os.writeObject(myBox); 
          
          
            15
          
          
             os.close(); 
          
          
            16
          
                       FileInputStream fi=
          
            new
          
           FileInputStream("F:\\foo.ser"
          
            ); 
          
          
            17
          
                       ObjectInputStream oi=
          
            new
          
          
             ObjectInputStream(fi); 
          
          
            18
          
                       Box box=
          
            (Box)oi.readObject(); 
          
          
            19
          
          
             oi.close(); 
          
          
            20
          
                       System.out.println(box.height+","+
          
            box.width); 
          
          
            21
          
                   } 
          
            catch
          
          
             (Exception e) { 
          
          
            22
          
          
             e.printStackTrace(); 
          
          
            23
          
          
             } 
          
          
            24
          
          
             } 
          
          
            25
          
          
            26
          
          
            public
          
          
            int
          
          
             getWidth() { 
          
          
            27
          
          
            return
          
          
             width; 
          
          
            28
          
          
             } 
          
          
            29
          
          
            public
          
          
            void
          
           setWidth(
          
            int
          
          
             width) { 
          
          
            30
          
          
            this
          
          .width =
          
             width; 
          
          
            31
          
          
             } 
          
          
            32
          
          
            public
          
          
            int
          
          
             getHeight() { 
          
          
            33
          
          
            return
          
          
             height; 
          
          
            34
          
          
             } 
          
          
            35
          
          
            public
          
          
            void
          
           setHeight(
          
            int
          
          
             height) { 
          
          
            36
          
          
            this
          
          .height =
          
             height; 
          
          
            37
          
          
             } 
          
          
            38
          
           }
        
      

  6、相關注意事項

  a)當一個父類實現序列化,子類自動實現序列化,不需要顯式實現Serializable接口;
  b)當一個對象的實例變量引用其他對象,序列化該對象時也把引用對象進行序列化;
  c)并非所有的對象都可以序列化,至于為什么不可以,有很多原因了,比如:

  1.安全方面的原因,比如一個對象擁有private,public等field,對于一個要傳輸的對象,比如寫到文件,或者進行rmi傳輸 等等,在序列化進行傳輸的過程中,這個對象的private等域是不受保護的。
  2. 資源分配方面的原因,比如socket,thread類,如果可以序列化,進行傳輸或者保存,也無法對他們進行重新的資源分配,而且,也是沒有必要這樣實現。

?

  serialVersionUID

  序列化運行時使用一個稱為 serialVersionUID 的版本號與每個可序列化類相關聯,該序列號在反序列化過程中用于驗證序列化對象的發送者和接收者是否為該對象加載了與序列化兼容的類。如果接收者加載的該對象的類的 serialVersionUID 與對應的發送者的類的版本號不同,則反序列化將會導致 ? InvalidClassException 。可序列化類可以通過聲明名為? "serialVersionUID" ?的字段(該字段必須是靜態 (static)、最終 (final) 的? long ?型字段)顯式聲明其自己的 serialVersionUID:

       ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
    

  如果可序列化類未顯式聲明 serialVersionUID,則序列化運行時將基于該類的各個方面計算該類的默認 serialVersionUID 值,如“Java(TM) 對象序列化規范”中所述。不過, 強烈建議 ?所有可序列化類都顯式聲明 serialVersionUID 值 ,原因是計算默認的 serialVersionUID 對類的詳細信息具有較高的敏感性,根據編譯器實現的不同可能千差萬別,這樣在反序列化過程中可能會導致意外的? InvalidClassException 。因此,為保證 serialVersionUID 值跨不同 java 編譯器實現的一致性,序列化類必須聲明一個明確的 serialVersionUID 值。還強烈建議使用? private ?修飾符顯示聲明 serialVersionUID(如果可能),原因是這種聲明僅應用于直接聲明類 -- serialVersionUID 字段作為繼承成員沒有用處。數組類不能聲明一個明確的 serialVersionUID,因此它們總是具有默認的計算值,但是數組類沒有匹配 serialVersionUID 值的要求。?

java.io.Serializable淺析


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产精品久久久99 | 日日拍夜夜嗷嗷叫视频 | 亚洲国产欧美日韩一区二区三区 | 伊人成人久久 | 狠狠久久久久久亚洲综合网 | 成人国产第一区在线观看 | 三级不卡 | 色xxx | 98在线视频噜噜噜国产 | 99爱免费 | 午夜dj影院在线视频观看完整 | 精品视频在线免费播放 | 国产亚洲精品激情一区二区三区 | 日本一区二区三区四区在线观看 | 亚洲狠狠婷婷综合久久久久图片 | 福利一区在线视频 | 欧美午夜片 | 欧美大片在线观看成人 | 国产精品久久久久精 | 久久这里只有免费精品6www | 亚洲欧美日韩中文无线码 | 欧美性猛交ⅹxxx乱大交免费 | 青草娱乐极品免费视频 | 最近中文字幕无吗免费视频 | 波多野结衣二区 | 夜夜爽夜夜叫夜夜高潮漏水 | 日本一级www乱码在线 | 2019最新四虎免费8848 | 日本操操操 | 欧美激情免费观看 | 视色视频 | 91香蕉国产亚洲一区二区三区 | 国产v片成人影院在线观看 国产v视频 | 乱人伦中文字幕在线看 | 韩国色三级伦不卡高清在线观看 | 四虎1515hh免费大炮社区 | 中文字幕亚洲区 | 国产精品成aⅴ人片在线观看 | 波多野结衣与公中出中文字幕 | 69午夜| 精品久久一区 |