java中的序列化解析
一、序列化
為了將對象進行網(wǎng)絡(luò)傳輸或者是持久化,我們需要將對象的狀態(tài)信息轉(zhuǎn)換為可以存儲或者傳輸?shù)男问健?/p>
這個轉(zhuǎn)換的過程就叫序列化
jre能力
Jre本身提供了序列化的支持,我們可以調(diào)用outputStream的writeObject方法
如果讓Java幫我們做的話,我們需要實現(xiàn)Serializable接口,這個接口是一個mini接口,沒有需要實現(xiàn)的方法,說白了,只是做一個標記。
package freeedu.test; import java.io.*; /** * @author 木子的晝夜編程 */ public class SerTest { public static void main(String[] args) throws Exception { // 創(chuàng)建對象 Person p = new Person("小花", 18, "女"); // 創(chuàng)建ObjectOutputStream ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("E:/MyNote/obj/Person.obj")); // 持久化 outputStream.writeObject(p); } } // 人 未實現(xiàn)Serializable class Person{ String name; int age; String gender; public Person(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } }
讀者朋友仔細看看,這樣寫對嗎?
一般問你對不對,那肯定就是不對啦!
使用JRE自帶序列化功能,被序列化的對象必須實現(xiàn)Serializable,否則就會報錯
下面才是正確的寫法:
package freeedu.test; import java.io.*; /** * @author 木子的晝夜編程 */ public class SerTest { public static void main(String[] args) throws Exception { // 創(chuàng)建對象 Person p = new Person("小花", 18, "女"); // 創(chuàng)建ObjectOutputStream ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("E:/MyNote/obj/Person.obj")); // 持久化 outputStream.writeObject(p); } } // 人 實現(xiàn)Serializable class Person implements Serializable{ String name; int age; String gender; public Person(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } }
執(zhí)行成功之后,看一看文件內(nèi)容?
看不懂?沒關(guān)系,我們可以反序列化,再看內(nèi)容
package freeedu.test; import java.io.*; /** * @author 木子的晝夜編程 */ public class DesTest { public static void main(String[] args) throws Exception { // 創(chuàng)建ObjectInputStream ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("E:/MyNote/obj/Person.obj")); // 讀取對象 Object o = inputStream.readObject(); // 判斷對象持久化對象是不是Person if (o instanceof Person) { // 如果是的話 強轉(zhuǎn) Person p = (Person) o; // 打印信息 System.out.println(p.age); System.out.println(p.name); System.out.println(p.gender); } } }
Serializable
可以看到,他只是一個接口,沒有任何需要實現(xiàn)的內(nèi)容。
其他
當然了,這只是Java自帶的序列化,我們平時網(wǎng)絡(luò)傳輸?shù)葧褂玫胶芏嗥渌蛄谢?/p>
比如:
- Json序列化
- 谷歌Gson的Json 、阿里的FastJson 、Jackson 等
- ProtoBuff序列化 據(jù)說做游戲的很多用這個 是谷歌出的 會大大節(jié)省傳輸流量
二、Serializable 接口
我們看java自帶序列化,需要實現(xiàn)一個Serializable,而實現(xiàn)這個接口,要求我們需要添加一個serialVersionUID 屬性,就像下邊這樣
// 人 class Person implements Serializable{ // 定義serialVersionUID private static final long serialVersionUID = 8940196742313994740L; String name; int age; String gender; public Person(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } }
如果你不定義這個serialVersionUID,jdk會根據(jù)序列化類的信息,比如字段等自動生成一個,但是你如果修改了這個類(比如添加字段),然后再反序列化沒有修改之前序列化的內(nèi)容就會報錯
比如我們修改一下Person類,然后反序列化一下上邊那個文件
class Person implements Serializable{ String name; int age; String gender; String aaaaaaa; public Person(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } }
如果Person類在序列化的時候定義了serialVersionUID,那么就不會出現(xiàn)這個問題
這個serialVersionUID很像是我們的銀行卡號,如果你的銀行卡沒卡號,只是根據(jù)你的手機號,或者是你的姓名進行綁定,那么當你手機號變更了,或者名稱變更了,那么就對應(yīng)不上你的卡了。所以我們銀行卡都有一個卡號,這個卡號隨銀行卡產(chǎn)生而產(chǎn)生,隨銀行卡注銷而注銷。
到此這篇關(guān)于java中的序列化解析的文章就介紹到這了,更多相關(guān)java序列化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java數(shù)組的三種擴容方式以及程序?qū)崿F(xiàn)詳解
這篇文章主要介紹了java數(shù)組的三種擴容方式以及程序?qū)崿F(xiàn)詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-12-12Java實現(xiàn)Timer的定時調(diào)度函數(shù)schedule的四種用法
本文主要介紹了Java實現(xiàn)Timer的定時調(diào)度函數(shù)schedule的四種用法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-04-04IntelliJ IDEA 創(chuàng)建spring boot 的Hello World 項目(圖解)
這篇文章主要介紹了IntelliJ IDEA 創(chuàng)建spring boot 的Hello World 項目的步驟詳解,需要的朋友可以參考下2018-01-01