java中的序列化解析
一、序列化
為了將對象進(jìn)行網(wǎng)絡(luò)傳輸或者是持久化,我們需要將對象的狀態(tài)信息轉(zhuǎn)換為可以存儲或者傳輸?shù)男问健?/p>
這個(gè)轉(zhuǎn)換的過程就叫序列化
jre能力
Jre本身提供了序列化的支持,我們可以調(diào)用outputStream的writeObject方法
如果讓Java幫我們做的話,我們需要實(shí)現(xiàn)Serializable接口,這個(gè)接口是一個(gè)mini接口,沒有需要實(shí)現(xiàn)的方法,說白了,只是做一個(gè)標(biāo)記。
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); } } // 人 未實(shí)現(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; } }
讀者朋友仔細(xì)看看,這樣寫對嗎?
一般問你對不對,那肯定就是不對啦!
使用JRE自帶序列化功能,被序列化的對象必須實(shí)現(xiàn)Serializable,否則就會報(bào)錯(cuò)
下面才是正確的寫法:
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); } } // 人 實(shí)現(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) { // 如果是的話 強(qiáng)轉(zhuǎn) Person p = (Person) o; // 打印信息 System.out.println(p.age); System.out.println(p.name); System.out.println(p.gender); } } }
Serializable
可以看到,他只是一個(gè)接口,沒有任何需要實(shí)現(xiàn)的內(nèi)容。
其他
當(dāng)然了,這只是Java自帶的序列化,我們平時(shí)網(wǎng)絡(luò)傳輸?shù)葧褂玫胶芏嗥渌蛄谢?/p>
比如:
- Json序列化
- 谷歌Gson的Json 、阿里的FastJson 、Jackson 等
- ProtoBuff序列化 據(jù)說做游戲的很多用這個(gè) 是谷歌出的 會大大節(jié)省傳輸流量
二、Serializable 接口
我們看java自帶序列化,需要實(shí)現(xiàn)一個(gè)Serializable,而實(shí)現(xiàn)這個(gè)接口,要求我們需要添加一個(gè)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; } }
如果你不定義這個(gè)serialVersionUID,jdk會根據(jù)序列化類的信息,比如字段等自動(dòng)生成一個(gè),但是你如果修改了這個(gè)類(比如添加字段),然后再反序列化沒有修改之前序列化的內(nèi)容就會報(bào)錯(cuò)
比如我們修改一下Person類,然后反序列化一下上邊那個(gè)文件
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類在序列化的時(shí)候定義了serialVersionUID,那么就不會出現(xiàn)這個(gè)問題
這個(gè)serialVersionUID很像是我們的銀行卡號,如果你的銀行卡沒卡號,只是根據(jù)你的手機(jī)號,或者是你的姓名進(jìn)行綁定,那么當(dāng)你手機(jī)號變更了,或者名稱變更了,那么就對應(yīng)不上你的卡了。所以我們銀行卡都有一個(gè)卡號,這個(gè)卡號隨銀行卡產(chǎn)生而產(chǎn)生,隨銀行卡注銷而注銷。
到此這篇關(guān)于java中的序列化解析的文章就介紹到這了,更多相關(guān)java序列化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java數(shù)組的三種擴(kuò)容方式以及程序?qū)崿F(xiàn)詳解
這篇文章主要介紹了java數(shù)組的三種擴(kuò)容方式以及程序?qū)崿F(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Java實(shí)現(xiàn)Timer的定時(shí)調(diào)度函數(shù)schedule的四種用法
本文主要介紹了Java實(shí)現(xiàn)Timer的定時(shí)調(diào)度函數(shù)schedule的四種用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04IntelliJ IDEA 創(chuàng)建spring boot 的Hello World 項(xiàng)目(圖解)
這篇文章主要介紹了IntelliJ IDEA 創(chuàng)建spring boot 的Hello World 項(xiàng)目的步驟詳解,需要的朋友可以參考下2018-01-01Java自定義注解實(shí)現(xiàn)Redis自動(dòng)緩存的方法
本篇文章主要介紹了Java自定義注解實(shí)現(xiàn)Redis自動(dòng)緩存的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04Java Lambda表達(dá)式原理及多線程實(shí)現(xiàn)
這篇文章主要介紹了Java Lambda表達(dá)式原理及多線程實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07