java中的序列化解析
一、序列化
為了將對(duì)象進(jìn)行網(wǎng)絡(luò)傳輸或者是持久化,我們需要將對(duì)象的狀態(tài)信息轉(zhuǎn)換為可以存儲(chǔ)或者傳輸?shù)男问健?/p>
這個(gè)轉(zhuǎn)換的過(guò)程就叫序列化
jre能力
Jre本身提供了序列化的支持,我們可以調(diào)用outputStream的writeObject方法
如果讓Java幫我們做的話,我們需要實(shí)現(xiàn)Serializable接口,這個(gè)接口是一個(gè)mini接口,沒(méi)有需要實(shí)現(xiàn)的方法,說(shuō)白了,只是做一個(gè)標(biāo)記。
package freeedu.test;
import java.io.*;
/**
* @author 木子的晝夜編程
*/
public class SerTest {
public static void main(String[] args) throws Exception {
// 創(chuàng)建對(duì)象
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ì)看看,這樣寫(xiě)對(duì)嗎?
一般問(wèn)你對(duì)不對(duì),那肯定就是不對(duì)啦!
使用JRE自帶序列化功能,被序列化的對(duì)象必須實(shí)現(xiàn)Serializable,否則就會(huì)報(bào)錯(cuò)

下面才是正確的寫(xiě)法:
package freeedu.test;
import java.io.*;
/**
* @author 木子的晝夜編程
*/
public class SerTest {
public static void main(String[] args) throws Exception {
// 創(chuàng)建對(duì)象
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)容?

看不懂?沒(mé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"));
// 讀取對(duì)象
Object o = inputStream.readObject();
// 判斷對(duì)象持久化對(duì)象是不是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è)接口,沒(méi)有任何需要實(shí)現(xiàn)的內(nèi)容。
其他
當(dāng)然了,這只是Java自帶的序列化,我們平時(shí)網(wǎng)絡(luò)傳輸?shù)葧?huì)使用到很多其他序列化。
比如:
- Json序列化
- 谷歌Gson的Json 、阿里的FastJson 、Jackson 等
- ProtoBuff序列化 據(jù)說(shuō)做游戲的很多用這個(gè) 是谷歌出的 會(huì)大大節(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會(huì)根據(jù)序列化類的信息,比如字段等自動(dòng)生成一個(gè),但是你如果修改了這個(gè)類(比如添加字段),然后再反序列化沒(méi)有修改之前序列化的內(nèi)容就會(huì)報(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,那么就不會(huì)出現(xiàn)這個(gè)問(wèn)題
這個(gè)serialVersionUID很像是我們的銀行卡號(hào),如果你的銀行卡沒(méi)卡號(hào),只是根據(jù)你的手機(jī)號(hào),或者是你的姓名進(jìn)行綁定,那么當(dāng)你手機(jī)號(hào)變更了,或者名稱變更了,那么就對(duì)應(yīng)不上你的卡了。所以我們銀行卡都有一個(gè)卡號(hào),這個(gè)卡號(hào)隨銀行卡產(chǎn)生而產(chǎn)生,隨銀行卡注銷而注銷。
到此這篇關(guān)于java中的序列化解析的文章就介紹到這了,更多相關(guān)java序列化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java如何使用流去除集合中某個(gè)字段為空的對(duì)象
這篇文章主要給大家介紹了關(guān)于Java如何使用流去除集合中某個(gè)字段為空的對(duì)象,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-08-08
java數(shù)組的三種擴(kuò)容方式以及程序?qū)崿F(xiàn)詳解
這篇文章主要介紹了java數(shù)組的三種擴(kuò)容方式以及程序?qū)崿F(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
Java實(shí)現(xiàn)Timer的定時(shí)調(diào)度函數(shù)schedule的四種用法
本文主要介紹了Java實(shí)現(xiàn)Timer的定時(shí)調(diào)度函數(shù)schedule的四種用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
IntelliJ IDEA 創(chuàng)建spring boot 的Hello World 項(xiàng)目(圖解)
這篇文章主要介紹了IntelliJ IDEA 創(chuàng)建spring boot 的Hello World 項(xiàng)目的步驟詳解,需要的朋友可以參考下2018-01-01
Java自定義注解實(shí)現(xiàn)Redis自動(dòng)緩存的方法
本篇文章主要介紹了Java自定義注解實(shí)現(xiàn)Redis自動(dòng)緩存的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04
詳解MyBatisPlus邏輯刪除與唯一索引沖突問(wèn)題
這篇文章主要介紹了詳解MyBatisPlus邏輯刪除與唯一索引沖突問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Java Lambda表達(dá)式原理及多線程實(shí)現(xiàn)
這篇文章主要介紹了Java Lambda表達(dá)式原理及多線程實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07

