一文詳解Java對象的序列化和反序列化
Java 對象的序列化和反序列化是一種將對象轉(zhuǎn)換成字節(jié)流并存儲在硬盤或網(wǎng)絡(luò)中,以及從字節(jié)流中重新加載對象的操作。Java 的序列化和反序列化提供了一種方便的方式,使得可以將對象在不同的應(yīng)用程序之間進(jìn)行交互。

一、什么是 Java 序列化和反序列化?
Java 對象的序列化是將 Java 對象轉(zhuǎn)換成字節(jié)流的過程,可用于持久化數(shù)據(jù),傳輸數(shù)據(jù)等。序列化是將 Java 對象的狀態(tài)表示為字節(jié)序列的過程,可以通過網(wǎng)絡(luò)傳送,存儲到文件中或者使用其他的持久化技術(shù),如數(shù)據(jù)庫等。序列化后的字節(jié)流可以被傳輸給遠(yuǎn)程系統(tǒng),并在那里重新構(gòu)造成原始對象。Java 序列化是一個將對象轉(zhuǎn)化為字節(jié)流的過程。
Java 對象的反序列化是將字節(jié)流重新恢復(fù)為原始對象的過程。反序列化是將字節(jié)流轉(zhuǎn)化為對象的過程。反序列化是對象序列化的逆過程,通過反序列化操作能夠在接收端恢復(fù)出與發(fā)送端相同的對象。當(dāng)我們需要對存儲的對象進(jìn)行讀取操作時,就需要對序列化的字節(jié)流進(jìn)行反序列化操作,將字節(jié)流轉(zhuǎn)化為原始的對象信息。
二、序列化和反序列化的實現(xiàn)方式
Java 中的序列化和反序列化可以通過實現(xiàn) Serializable 接口來完成。Serializable 是一種標(biāo)記接口,它沒有方法定義,但它具有一個特別的作用,就是用于在描述 java 類可序列化時做類型判斷的信息。當(dāng)一個類實現(xiàn) Serializable 接口時,表明這個類是可序列化的。Serializable 接口只是一個標(biāo)識接口,我們并不需要重載任何方法。
在實現(xiàn) Serializable 接口后,就可以通過 ObjectOutputStream 來將對象序列化,并將序列化后的字節(jié)流輸出到文件或網(wǎng)絡(luò)中;同時,也可以通過 ObjectInputStream 來將序列化后的字節(jié)流反序列化成對象。 java.io.ObjectOutputStream 繼承自 OutputStream 類,因此可以將序列化后的字節(jié)序列寫入到文件、網(wǎng)絡(luò)等輸出流中。
來看 ObjectOutputStream 的構(gòu)造方法: ObjectOutputStream(OutputStream out)
一個對象要想序列化,必須滿足兩個條件:
- 該類必須實現(xiàn)
java.io.Serializable接口open in new window,否則會拋出NotSerializableException。 - 該類的所有字段都必須是可序列化的。如果一個字段不需要序列化,則需要使用
transient關(guān)鍵字open in new window進(jìn)行修飾。 - 該構(gòu)造方法接收一個 OutputStream 對象作為參數(shù),用于將序列化后的字節(jié)序列輸出到指定的輸出流中。
示例代碼如下:
import java.io.*;
public class SerializationDemo {
public static void main(String[] args) {
// 序列化對象
Person person = new Person("Tom", 20);
try {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("person.txt"));
objectOutputStream.writeObject(person);
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
// 反序列化對象
try {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("person.txt"));
Person restoredPerson = (Person) objectInputStream.readObject();
System.out.println(restoredPerson);
objectInputStream.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}在上述代碼中,我們定義了一個 Person 類,該類實現(xiàn)了 Serializable 接口。在序列化過程中,我們使用 ObjectOutputStream 類將 person 對象寫出到文件中;在反序列化過程中,我們使用 ObjectInputStream 類讀取文件中的字節(jié)流,并將其轉(zhuǎn)換為 Person 對象。
三、序列化和反序列化的注意事項
- 私有化序列號屬性
序列化和反序列化需要使用對象的序列號屬性(serialVersionUID)來判斷版本號是否一致,從而防止在新版本和舊版本之間發(fā)生不兼容的情況。如果沒有顯式地聲明 serialVersionUID,則編譯器會自動生成一個 serialVersionUID,但這種方式是不可靠的,因為在修改過程中可能會產(chǎn)生 serialVersionUID 的變化,從而導(dǎo)致不兼容問題。
因此,在 Java 序列化中,最好顯式地聲明 serialVersionUID 屬性,并進(jìn)行私有化,避免意外的修改。例如:
private static final long serialVersionUID = 1L;
- 實現(xiàn) readObject 和 writeObject 方法
readObject 和 writeObject 是在序列化和反序列化過程中用于自定義序列化的方法。通常情況下,我們可以直接使用默認(rèn)的序列化方法,但是有時我們需要對序列化內(nèi)容進(jìn)行一些處理,這時就需要實現(xiàn) readObject 和 writeObject 方法。例如,對于對象中敏感數(shù)據(jù)的處理,我們可以在 writeObject 方法中對數(shù)據(jù)進(jìn)行加密處理,在 readObject 方法中解密處理。
需要注意的是,在實現(xiàn) readObject 和 writeObject 方法時,必須要調(diào)用默認(rèn)方法,默認(rèn)方法可以通過 ObjectInputStream 和 ObjectOutputStream 類的 defaultReadObject 和 defaultWriteObject 方法調(diào)用。
四、序列化和反序列化的優(yōu)點(diǎn)和缺點(diǎn)
序列化和反序列化的優(yōu)點(diǎn)是:
對象的序列化方便了對象在不同應(yīng)用之間的傳遞、存儲和恢復(fù)。
通過序列化可以實現(xiàn)分布式計算,在不同的機(jī)器上對同一對象進(jìn)行操作和協(xié)作。
序列化提供了數(shù)據(jù)持久化的能力,即將對象的狀態(tài)保存在硬盤等介質(zhì)中,下次可以直接從硬盤中讀取數(shù)據(jù),避免了頻繁地進(jìn)行數(shù)據(jù)庫讀寫操作。
序列化和反序列化的缺點(diǎn)是:
在進(jìn)行序列化和反序列化操作時,需要消耗額外的時間和開銷,特別是當(dāng)對象比較大或者嵌套較深的時候,可能會導(dǎo)致嚴(yán)重的性能問題。
序列化和反序列化可能存在安全性問題,如果被攻擊者篡改了序列化后的字節(jié)流數(shù)據(jù),那么反序列化后的對象可能會出現(xiàn)意外行為,如獲得不應(yīng)該獲得的權(quán)限。
五、總結(jié)
Java 對象的序列化和反序列化是一種將對象轉(zhuǎn)換成字節(jié)流并存儲在硬盤或網(wǎng)絡(luò)中,以及從字節(jié)流中重新加載對象的操作。序列化和反序列化均需要實現(xiàn) Serializable 接口,并使用 ObjectOutputStream 和 ObjectInputStream 類來完成。序列化和反序列化可以方便地實現(xiàn)對象在不同應(yīng)用之間的傳遞、存儲和恢復(fù)等功能,但也存在一些缺點(diǎn),如可能會導(dǎo)致嚴(yán)重的性能問題和安全性問題。在使用過程中,需要根據(jù)具體的業(yè)務(wù)場景和需求進(jìn)行選擇和優(yōu)化,以達(dá)到最佳的效果。

在實際的 Java 開發(fā)中,序列化和反序列化是一個非常常見的操作,例如在分布式系統(tǒng)中,需要將對象序列化后通過網(wǎng)絡(luò)傳輸,在不同的機(jī)器上進(jìn)行反序列化以得到原始對象。
以下是一些使用序列化和反序列化的示例場景:
- 緩存
在實際的開發(fā)中,我們經(jīng)常需要對一些數(shù)據(jù)進(jìn)行緩存,使用序列化可以將對象序列化為字節(jié)數(shù)組,然后將字節(jié)數(shù)組存儲到文件或者緩存中。當(dāng)需要使用緩存中的對象時,再進(jìn)行反序列化操作,重新獲得原始對象。
- 遠(yuǎn)程調(diào)用
在分布式系統(tǒng)中,需要將對象序列化后通過網(wǎng)絡(luò)傳輸,在不同的機(jī)器上進(jìn)行反序列化以得到原始對象。例如在 Dubbo 框架中,就使用了對象序列化和反序列化機(jī)制。
- 持久化數(shù)據(jù)
在實際的開發(fā)中,我們需要將某些對象的狀態(tài)保存到數(shù)據(jù)庫或者文件中,使用序列化可以將對象序列化為字節(jié)數(shù)組,然后將字節(jié)數(shù)組存儲到數(shù)據(jù)庫或者文件中。當(dāng)需要讀取數(shù)據(jù)時,再進(jìn)行反序列化操作,獲得原始對象。
一般使用 Java 序列化和反序列化只需要實現(xiàn) Serializable 接口即可,但是也可以使用一些工具依賴來簡化操作。以下是一些常用的序列化和反序列化工具依賴:
1. Jackson
Jackson 是一個非常常用的序列化和反序列化工具,在 Spring Boot 等框架中也被廣泛使用。Jackson 可以將對象序列化為 JSON 或者 XML 格式,同時也可以將 JSON 或者 XML 反序列化為對象。
2. Gson
Gson 是另一個常用的序列化和反序列化工具,同樣可以將對象序列化為 JSON 格式,也可以將 JSON 反序列化為對象。
3. Protobuf
Protobuf 是 Google 開源的一種輕量級、高效、可擴(kuò)展的序列化框架,支持多種編程語言。與 Java 序列化相比,Protobuf 使用效率更高,序列化后的字節(jié)流更小,但需要預(yù)定義消息格式。
4. Kyro
Kryo 是一個高性能的 Java 序列化和反序列化工具,可以將 Java 對象序列化為字節(jié)數(shù)組,適合于網(wǎng)絡(luò)通信和數(shù)據(jù)持久化等場景。Kryo 能夠快速地序列化和反序列化 Java 對象,相對于 Java 自帶的序列化機(jī)制,它的速度更快,序列化后的字節(jié)數(shù)組也更小。
以上是一些常用的序列化和反序列化工具依賴,根據(jù)不同的業(yè)務(wù)需求和場景需要選擇適合的工具。
到此這篇關(guān)于一文詳解Java對象的序列化和反序列化的文章就介紹到這了,更多相關(guān)Java對象的序列化和反序列化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot實現(xiàn)多環(huán)境配置文件切換教程詳解
很多時候,我們項目在開發(fā)環(huán)境和生成環(huán)境的環(huán)境配置是不一樣的,例如,數(shù)據(jù)庫配置,這個時候就需要切換環(huán)境配置文件。本文將詳細(xì)講解SpringBoot如何切換配置文件,需要的可以參考一下2022-03-03
Java使用application.property讀取文件里面的值
本文通過實例代碼給大家介紹了Java使用application.property讀取文件里面的值,需要的朋友可以參考下2018-10-10
javax.management.InvalidApplicationException的問題解決
javax.management.InvalidApplicationException是與Java Management Extensions (JMX) API相關(guān)的一個常見異常,本文主要介紹了javax.management.InvalidApplicationException的問題解決,感興趣的可以了解一下2024-08-08
java使用DelayQueue實現(xiàn)延時任務(wù)
項目中經(jīng)常會用到類似一些需要延遲執(zhí)行的功能,比如緩存,java提供了DelayQueue來很輕松的實現(xiàn)這種功能,下面小編就來和大家介紹一下如何使用DelayQueue實現(xiàn)延時任務(wù)吧2023-10-10
IDEA實現(xiàn)Maven項目創(chuàng)建并連接Tomcat方式
Maven是一款由Apache開發(fā)的項目管理工具,主要用于Java項目的構(gòu)建和依賴管理,它通過pom.xml文件自動管理項目依賴的jar包,簡化了項目構(gòu)建過程,Maven支持項目從編寫源代碼到編譯、測試、打包、部署的全過程管理,其依賴管理功能免去了手動添加jar包的麻煩2024-10-10
Idea安裝及涉及springboot詳細(xì)配置的圖文教程
這篇文章主要介紹了Idea安裝及涉及springboot詳細(xì)配置,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10
SpringBoot解決Required?String?parameter?xxx?is?not?prese
這篇文章主要介紹了SpringBoot解決Required?String?parameter?xxx?is?not?present問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01

