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

java.io.Serializable淺析

系統(tǒng) 2153 0

java.io.Serializable淺析

?

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

        
          
            1
          
          
            public
          
          
            interface
          
          
             Serializable { 
          
          
            2
          
           }
        
      

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

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

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

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

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

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

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

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

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

?

  1、序列化是干什么的?

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

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

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

  3、當對一個對象實現(xiàn)序列化時,究竟發(fā)生了什么?

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

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

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

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

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

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

  1.安全方面的原因,比如一個對象擁有private,public等field,對于一個要傳輸?shù)膶ο螅热鐚懙轿募蛘哌M行rmi傳輸 等等,在序列化進行傳輸?shù)倪^程中,這個對象的private等域是不受保護的。
  2. 資源分配方面的原因,比如socket,thread類,如果可以序列化,進行傳輸或者保存,也無法對他們進行重新的資源分配,而且,也是沒有必要這樣實現(xiàn)。

?

  serialVersionUID

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

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

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

java.io.Serializable淺析


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

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

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久亚洲精品人成综合网 | 四虎永久免费在线 | 国语一级毛片 | 亚洲国产综合在线 | 瑟瑟视频在线观看 | 国产免费一区二区在线看 | 欧美人牲囗毛片 | 久久福利资源国产精品999 | 国产羞羞视频在线播放 | 看免费的毛片 | 精品国产品国语在线不卡丶 | 一级日本强免费 | 亚洲三级欧美 | 伊人久色| 久久精品伊人波多野结 | 四虎四虎1515hhcom | 国产成人久久精品一区二区三区 | 日本一视频一区视频二区 | 久久精热| 亚洲精品视频二区 | 色视频在线 | 一本伊大人香蕉久久网手机 | 欧美黄色录像 | 黄色片免费在线观看视频 | 亚洲性一区| 久久艹伊人 | 精品91精品91精品国产片 | 手机看片日韩日韩韩 | 伊人222综合| 久久久精| 亚洲精品久久婷婷爱久久婷婷 | 波多野结衣免费免费视频一区 | 97视频在线免费 | 四虎2020 | 亚洲国产精品一区 | 免费一级a毛片在线播放视 免费一级成人毛片 | 伊人久久婷婷丁香六月综合基地 | 久久久久久久久久福利 | 五月婷婷六月综合 | 一区中文字幕 | 国产在线视频精品视频免费看 |