Java序列化反序化

      網友投稿 917 2022-05-29

      一、什么是序列化和反序列化

      Java序列化就是指把Java對象轉換為字節序列的過程

      Java反序列化就是指把字節序列恢復為Java對象的過程。

      二、為什么要把一個對象序列化

      正常情況下,Java new出的對象,是保存在內存當中的,是不能持久化保存的,也不能直接在網絡中傳輸,如何解決呢?就是把Java對象轉換為byte字節數據,以字節的方式去實現持久化保存和網絡傳輸。而反序列化,就是把須列化后的數據,重新恢復成內存中的Java對象。

      總之,序列化,就是對一個Java對象的保存和重建的過程。

      三、Java實現序列化的過程

      為了讓一個Java對象能序列化,我們需要為這個Java對象實現Serializable接口,像下面這樣,這個方法和普通的Bean來說,多繼承了這個接口,這個接口沒有實現實現任何方法,它是為什么告訴編譯器,這個接口可以序列化。

      Java序列化和反序化

      @Data public class User implements Serializable { private String name; private int age; private String sex; private String phone; }

      這個類可以序列化了,但如何序列化讓它能本地存儲呢?執行下面的write方法,將會在D盤根目錄下創建User類的序列化文件,執行read方法可以把序列化文件轉變成對象。

      public class Client { @Test public void write() throws Exception{ User user = new User(); user.setAge(15); user.setName("張三"); user.setPhone("123"); FileOutputStream fileOutputStream = new FileOutputStream("D://out.txt"); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); objectOutputStream.writeObject(user); } @Test public void read() throws Exception{ FileInputStream fileInputStream = new FileInputStream("D://out.txt"); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); User o = (User)objectInputStream.readObject(); System.out.println(o.toString()); } }

      read方法運行結果,序列化出來的對象,擁有序列化之前對象的值。

      四、不能被序列化的對象

      Java對象中,如果一個字段被transient修飾,或者這個字段是static靜態字段,這個類將不會被序列化,意味著,這個對象被序列化后,再次反序列化成Java對象后,對于的字段值為null。

      五、序列號的作用

      我們的類是不斷的變動的,我們把一個對象序列化到本地文件后,有一天,這個對象的類發送了改變,我們用這個改變后的類接收序號化文件,會發生什么?把name和age注釋掉,然后去反序列化。

      public class User implements Serializable { // private String name; // // transient private int age; private String sex; private String phone; } public class Client { @Test public void write() throws Exception{ User user = new User(); // user.setAge(15); // user.setName("張三"); user.setPhone("123"); FileOutputStream fileOutputStream = new FileOutputStream("D://out.txt"); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); objectOutputStream.writeObject(user); } @Test public void read() throws Exception{ FileInputStream fileInputStream = new FileInputStream("D://out.txt"); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); User o = (User)objectInputStream.readObject(); System.out.println(o.toString()); } }

      結果就是

      java.io.InvalidClassException: com.example.service.demo01.User; local class incompatible: stream classdesc serialVersionUID = -118799779803260725, local class serialVersionUID = 1681826866445576943

      這個報錯是什么意思?是這個類和序列化文件里的類的序列號不一樣,無法反序列化。

      這里出現了一個問題,什么是序列號?

      序列號是一個長整型的數據,一個類的序列號,是根據這個類的成員變量計算出來,如果成員變量發生改變,序列號也會發生改變,只有序列化文件的序列號和類的序列號相同,才能反序列化成功。

      所以這個報錯就很容易理解了,在改動前,類有三個變量,序列號的值假設是3,序列化的文件也是3,刪除一個變量后,只剩兩個變量,假設序列號是2,這樣和序列化文件的序列號就不一樣了,所以無法反序列化。

      有時候,我們希望,即使類發生了改變,也能反序列化成功,比如之前有現在只剩3個字段,序列化的文件有4個字段,我們只序列化現在的類有的字段,那該怎么做?

      我們可以手動為一個類設置序列號,像這樣:

      這樣,即使類發生了改變,但是序列號我們已經手動寫死了,之后類再怎么發生變化,反序列化也不會報錯,只會序列那化些還能對應上的值。

      Java

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:基因數據分析軟件遷移-Sambamba-0.7.0
      下一篇:Kubernetes 集群基本概念
      相關文章
      亚洲日本乱码卡2卡3卡新区| 99久久婷婷国产综合亚洲| 亚洲av日韩aⅴ无码色老头 | 亚洲欧洲自拍拍偷精品 美利坚 | 亚洲成AV人片在线观看| 亚洲综合AV在线在线播放| 亚洲人成影院在线无码观看| 偷自拍亚洲视频在线观看99| 风间由美在线亚洲一区| 久久久久亚洲国产AV麻豆| 激情无码亚洲一区二区三区| 国产精品无码亚洲精品2021| 午夜亚洲av永久无码精品| 国内成人精品亚洲日本语音 | 久久久久亚洲AV无码麻豆| 亚洲av日韩av无码| 色噜噜综合亚洲av中文无码| 亚洲综合男人的天堂色婷婷| 亚洲啪啪免费视频| 色噜噜亚洲男人的天堂| 亚洲熟妇自偷自拍另欧美| 亚洲国产成人久久综合| 爱爱帝国亚洲一区二区三区| 亚洲精品国产高清嫩草影院| 国产成人综合亚洲亚洲国产第一页| 亚洲自偷自偷偷色无码中文| 亚洲V无码一区二区三区四区观看| 婷婷久久久亚洲欧洲日产国码AV | 国产精品亚洲精品日韩电影| 亚洲国产日韩在线观频| 亚洲香蕉网久久综合影视| 亚洲AV无一区二区三区久久| 久久精品国产精品亚洲毛片| 亚洲中文字幕在线无码一区二区 | 亚洲精品中文字幕| 亚洲国产天堂久久综合| 亚洲色成人WWW永久网站| 亚洲日本一区二区| 亚洲av产在线精品亚洲第一站| 亚洲偷自拍另类图片二区| 国产亚洲福利一区二区免费看|