最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中序列化與反序列化的定義及代碼示例

 更新時間:2024年10月15日 08:34:25   作者:翠花也老了  
序列化是將對象狀態(tài)轉(zhuǎn)換為可存儲或傳輸格式的過程,反序列化則是將存儲或傳輸格式恢復(fù)為原始對象的逆過程,這篇文章主要介紹了Java中序列化與反序列化的相關(guān)資料,需要的朋友可以參考下

序列化與反序列化的定義

序列化(Serialization)與反序列化(Deserialization)是編程中常見的兩個概念,它們主要涉及到將數(shù)據(jù)結(jié)構(gòu)或?qū)ο鬆顟B(tài)轉(zhuǎn)換為可以存儲或傳輸?shù)母袷剑约皩⒋鎯騻鬏數(shù)母袷睫D(zhuǎn)換回原始的數(shù)據(jù)結(jié)構(gòu)或?qū)ο鬆顟B(tài)的過程。
這兩個過程在數(shù)據(jù)持久化、網(wǎng)絡(luò)通信、對象深拷貝等多個場景中發(fā)揮著重要作用。

序列化(Serialization)

序列化是指將數(shù)據(jù)結(jié)構(gòu)或?qū)ο鬆顟B(tài)轉(zhuǎn)換成可以存儲或傳輸?shù)母袷降倪^程。這個格式通常是平臺無關(guān)的,比如JSON、XML、二進(jìn)制格式等,以便可以在不同的系統(tǒng)或環(huán)境中進(jìn)行交換。序列化后的數(shù)據(jù)可以存儲在文件中,或者通過網(wǎng)絡(luò)發(fā)送給其他系統(tǒng)。

為什么需要序列化?

  • 數(shù)據(jù)持久化:將對象狀態(tài)保存到文件中,以便在程序關(guān)閉或系統(tǒng)重啟后能夠重新加載這些數(shù)據(jù)。
  • 網(wǎng)絡(luò)傳輸:在網(wǎng)絡(luò)通信中,數(shù)據(jù)需要在客戶端和服務(wù)器之間傳輸,序列化可以將對象轉(zhuǎn)換成字節(jié)流,便于在網(wǎng)絡(luò)上傳輸。
  • 對象深拷貝:通過序列化一個對象,然后立即進(jìn)行反序列化,可以實現(xiàn)對象的深拷貝。

反序列化(Deserialization)

反序列化是序列化的逆過程,即將序列化后的數(shù)據(jù)(如JSON、XML、二進(jìn)制格式等)轉(zhuǎn)換回原始的數(shù)據(jù)結(jié)構(gòu)或?qū)ο鬆顟B(tài)。這個過程允許程序在需要時重新構(gòu)建對象,并使用其原始數(shù)據(jù)。

為什么需要反序列化?

  • 數(shù)據(jù)恢復(fù):在程序啟動時,從文件中讀取序列化后的數(shù)據(jù),反序列化成對象,以恢復(fù)程序運行前的狀態(tài)。
  • 數(shù)據(jù)接收:在網(wǎng)絡(luò)通信中,接收到的序列化數(shù)據(jù)需要被反序列化成對象,以便在本地系統(tǒng)中使用。

Java的序列化

Java序列化是指將Java對象的狀態(tài)轉(zhuǎn)換為可以保存或傳輸?shù)母袷降倪^程。Java提供了多種序列化方式,以滿足不同的需求和場景。以下是Java序列化的幾種主要方式:

1. 實現(xiàn)Serializable接口

  • 特點:這是Java默認(rèn)的序列化方式,通過實現(xiàn)java.io.Serializable接口來標(biāo)記一個類可以被序列化。這種序列化方式是隱式的,會自動序列化所有非static和transient關(guān)鍵字修飾的成員變量。
  • 使用場景:適用于大多數(shù)需要序列化的場景,特別是當(dāng)對象的狀態(tài)需要被持久化或在網(wǎng)絡(luò)間傳輸時。

2. 實現(xiàn)Externalizable接口

  • 特點:與Serializable接口類似,但Externalizable接口提供了更高的靈活性。實現(xiàn)該接口的類必須手動實現(xiàn)writeExternal()和readExternal()方法,以控制序列化和反序列化的過程。
  • 使用場景:適用于需要精確控制序列化過程的場景,比如只序列化對象的某些部分,或者需要對序列化數(shù)據(jù)進(jìn)行加密等。

3. 使用JSON序列化庫

  • 常用庫:如Jackson、Gson等。
  • 特點:將對象轉(zhuǎn)換為JSON格式的字符串進(jìn)行序列化,可以跨語言、跨平臺進(jìn)行數(shù)據(jù)交換。JSON格式易于閱讀和編寫,也易于機(jī)器解析和生成。
  • 使用場景:適用于需要與其他語言或系統(tǒng)交互的場景,或者當(dāng)對象需要被存儲為文本格式時。

4. 使用XML序列化庫

  • 常用庫:如JAXB、XStream等。
  • 特點:將對象轉(zhuǎn)換為XML格式的字符串進(jìn)行序列化,同樣可以跨語言、跨平臺進(jìn)行數(shù)據(jù)交換。XML格式具有良好的可擴(kuò)展性和可讀性。
  • 使用場景:適用于需要遵循特定XML標(biāo)準(zhǔn)的場景,或者當(dāng)對象需要被存儲為易于人類閱讀的格式時。

5. 使用二進(jìn)制序列化庫

  • 常用庫:如Protocol Buffers(protobuf)、Apache Thrift、Apache Avro等。
  • 特點:將對象序列化為二進(jìn)制格式進(jìn)行傳輸和存儲,效率較高。這些庫通常提供了豐富的數(shù)據(jù)結(jié)構(gòu)和高效的編碼解碼算法。
  • 使用場景:適用于對性能要求較高的場景,比如需要頻繁序列化和反序列化大量數(shù)據(jù)的系統(tǒng)。

6. 其他序列化方式

  • Hessian序列化:Hessian是一種通過網(wǎng)絡(luò)傳輸和存儲Java對象的二進(jìn)制格式,可以跨語言、跨平臺使用,效率較高。
  • Kryo序列化:Kryo是一種高性能的Java序列化庫,序列化和反序列化速度都很快,但只能用于Java環(huán)境。

Java提供了多種序列化方式,每種方式都有其特點和適用場景。在實際應(yīng)用中,可以根據(jù)具體需求和場景選擇合適的方式進(jìn)行Java對象的序列化。需要注意的是,除了Java默認(rèn)的序列化方式外,其他方式通常需要引入相應(yīng)的第三方庫。

Java默認(rèn)序列化與反序列化示例

我們先將一些Java的變量和一個Car對象序列化到 d盤的一個名為 data.dat 的文件中。

/**
 * ObjectOutputStream 的使用,完成數(shù)據(jù)的序列化
 * ObjectOutputStream 是序列化
 */
public class ObjectOutputStreamDemo {

    public static void main(String[] args) throws IOException {
        //序列化后,保存到文本格式不是純文本txt,而是按照它的格式來保存
        String filePath = "d:\\data.dat";

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
        oos.writeInt(100);//int -> Integer(實現(xiàn)了Serializable)
        oos.writeBoolean(true);//boolean -> Boolean(實現(xiàn)了 Serializable)
        oos.writeChar('o');//char -> Character(實現(xiàn)了Serializable)
        oos.writeDouble(4.4);//double -> Double(實現(xiàn)了 Serializable)
        oos.writeUTF("對象輸出流");//String (實現(xiàn)了Serializable)
        oos.writeObject(new Car("xiaomi su7","Pro","Gulf Blue","300,000"));
        oos.close();
        System.out.println("數(shù)據(jù)以序列化的形式保存完成");
        /*
        如果Car沒有實現(xiàn) Serializable接口,會報錯如下:
        Exception in thread "main" java.io.NotSerializableException: org.example.io.demo.lession20.Car
        	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	        at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	        at org.example.io.demo.lession20.ObjectOutputStreamDemo.main(ObjectOutputStreamDemo.java:24)
         */
    }
}

@Data
class Car implements Serializable {
    private String name;
    private String type;
    private static String color ;
    private transient String price ;

    public Car(String name,String type,String color,String price){
        this.name = name;
        this.type = type;
        this.color = color;
        this.price = price;
    }
}

執(zhí)行main方法后,會在d盤根目錄下看到一個 data.dat的文件。

使用記事本打開,依稀可以看到點什么,但明顯不是txt格式的文本。

下面我們將這個文件反序列化至程序中并打印出來:

/**
 * 讀取序列化文件,并通過反序列化恢復(fù)數(shù)據(jù)
 * ObjectInputStream 是反序列化
 */
public class ObjectInputStreamDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //指定反序列化的文件
        String filePath = "d:\\data.dat";
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
        //讀取(即反序列化)的順序需要和保存數(shù)據(jù)(即序列化)的順序一致,否則會有異常
        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readDouble());
        System.out.println(ois.readUTF());
        System.out.println(ois.readObject().toString());
        ois.close();
    }
}

輸出結(jié)果為:

100
true
o
4.4
對象輸出流
Car(name=xiaomi su7, type=Pro, price=null)

Java 序列化與反序列化注意事項:

  • 讀寫順序要一致。
  • 序列化與反序列化對象要實現(xiàn) Serializable 接口。
  • 序列化中的類中,建議添加SerialVersionUID,為了提高版本的兼容性。
  • 序列化對象時,默認(rèn)將里面所有的屬性都進(jìn)行序列化,除了stati、transient 修飾的成員。
  • 序列化對象時,要求里面屬性的類型也需要實現(xiàn)序列化接口。
  • 序列化具備可繼承性,也就是如果某類已經(jīng)實現(xiàn)了序列化,則它的所有子類也默認(rèn)實現(xiàn)了序列化。

TIPS:static 和 transient 在序列化中的區(qū)別

static關(guān)鍵字

  • 定義:static關(guān)鍵字用于修飾類的成員變量和方法,使其成為類變量或類方法,而不是實例變量或?qū)嵗椒ān愖兞繉儆陬惐旧?,而非類的任何特定實例?/li>
  • 序列化行為:在序列化過程中,被static修飾的變量(即類變量)不會被序列化。這是因為static變量是類級別的,它們不屬于任何特定的對象實例,而是由所有實例共享。因此,序列化一個對象時,不會包含其類變量的值,因為類變量的值在JVM中是全局的,與特定的序列化實例無關(guān)。
  • 反序列化影響:反序列化一個對象時,被static修飾的變量會保持其在JVM中的當(dāng)前值,而不是從序列化數(shù)據(jù)中恢復(fù)。這是因為靜態(tài)變量是全局的,不受單個對象實例的序列化/反序列化過程影響。

transient關(guān)鍵字

  • 定義:transient關(guān)鍵字用于修飾類的成員變量,以指示該變量在序列化時不應(yīng)被序列化。
  • 序列化行為:當(dāng)一個對象被序列化時,所有非transient修飾的成員變量都會被序列化,而transient修飾的變量則會被忽略。這意味著,在序列化后的數(shù)據(jù)中,不會包含任何被transient修飾的變量的值。
  • 反序列化影響:在反序列化過程中,被transient修飾的變量將不會被恢復(fù)其序列化前的值。相反,它們會被初始化為默認(rèn)值(例如,數(shù)值類型的變量會被初始化為0或false,對象類型的變量會被初始化為null)。因此,開發(fā)者需要在反序列化后,根據(jù)需要手動為這些變量賦值。

二者對比表格

關(guān)鍵字定義序列化行為反序列化影響
static修飾類變量或類方法,屬于類本身不被序列化保持JVM中的當(dāng)前值
transient修飾成員變量,指示在序列化時忽略該變量被忽略,不被序列化被初始化為默認(rèn)值

總結(jié) 

到此這篇關(guān)于Java中序列化與反序列化的文章就介紹到這了,更多相關(guān)Java序列化與反序列化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java動態(tài)導(dǎo)出excel壓縮成zip下載的方法

    java動態(tài)導(dǎo)出excel壓縮成zip下載的方法

    這篇文章主要為大家詳細(xì)介紹了java動態(tài)導(dǎo)出excel壓縮成zip下載的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • java中的形參與實參的區(qū)別對比解析

    java中的形參與實參的區(qū)別對比解析

    文章講述了Java中形參和實參的區(qū)別,包括定義位置、作用階段、內(nèi)存分配和示例說明,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-11-11
  • intellij idea 將模塊打jar包的步驟詳解

    intellij idea 將模塊打jar包的步驟詳解

    這篇文章主要介紹了intellij idea 將模塊打jar包的步驟,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-09-09
  • SpringBoot中的條件注解使用示例詳解

    SpringBoot中的條件注解使用示例詳解

    SpringBoot條件注解用于動態(tài)控制Bean創(chuàng)建與配置加載,基于@Conditional機(jī)制,支持按類、Bean、屬性等條件判斷,廣泛應(yīng)用于多數(shù)據(jù)源等場景,提升應(yīng)用靈活性與智能化,接下來通過本文給大家講解SpringBoot中的條件注解使用,感興趣的朋友一起看看吧
    2025-08-08
  • Java 獲取服務(wù)器環(huán)境的實例詳解

    Java 獲取服務(wù)器環(huán)境的實例詳解

    這篇文章主要介紹了Java 獲取服務(wù)器環(huán)境的實例詳解的相關(guān)資料,這里提供實例和輸出結(jié)果,希望能幫助大家理解,需要的朋友可以參考下
    2017-07-07
  • SpringBoot 整合 Lettuce Redis的實現(xiàn)方法

    SpringBoot 整合 Lettuce Redis的實現(xiàn)方法

    這篇文章主要介紹了SpringBoot 整合 Lettuce Redis的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • SpringBoot+Swagger打造美觀API文檔的實戰(zhàn)指南

    SpringBoot+Swagger打造美觀API文檔的實戰(zhàn)指南

    在現(xiàn)代 Web 開發(fā)中,API 文檔是開發(fā)者和團(tuán)隊協(xié)作的重要組成部分,本文將詳細(xì)介紹如何在 SpringBoot2和SpringBoot3中集成Swagger,并展示多種接口文檔風(fēng)格,幫助開發(fā)者選擇適合自己項目的展示方式
    2025-08-08
  • 詳解springboot的多種配置方式

    詳解springboot的多種配置方式

    這篇文章主要介紹了springboot的多種配置方式,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • 關(guān)于spring?boot使用?jdbc+mysql?連接的問題

    關(guān)于spring?boot使用?jdbc+mysql?連接的問題

    這篇文章主要介紹了spring?boot使用?jdbc+mysql?連接,在這里mysql?8.x版本驅(qū)動包,要使用?com.mysql.cj.jdbc.Driver作為驅(qū)動類,文中給大家詳細(xì)介紹,需要的朋友可以參考下
    2022-03-03
  • 學(xué)習(xí)Java之如何正確地向上轉(zhuǎn)型與向下轉(zhuǎn)型

    學(xué)習(xí)Java之如何正確地向上轉(zhuǎn)型與向下轉(zhuǎn)型

    面向?qū)ο蟮牡谌齻€特征是多態(tài),實現(xiàn)多態(tài)有三個必要條件:繼承、方法重寫和向上轉(zhuǎn)型,在學(xué)習(xí)多態(tài)之前,我們還要先學(xué)習(xí)Java的類型轉(zhuǎn)換,本篇文章就來帶大家認(rèn)識什么是類型轉(zhuǎn)換,看看類型轉(zhuǎn)換都有哪幾種情況,以及如何避免類型轉(zhuǎn)換時出現(xiàn)異常
    2023-05-05

最新評論

安乡县| 博罗县| 北票市| 苏尼特左旗| 南京市| 凭祥市| 德昌县| 韶关市| 象州县| 宣恩县| 土默特右旗| 和龙市| 延庆县| 县级市| 隆回县| 湖口县| 阿合奇县| 普格县| 开化县| 门头沟区| 綦江县| 额济纳旗| 新和县| 松江区| 黔西| 商丘市| 荃湾区| 定南县| 高雄市| 集贤县| 上蔡县| 六盘水市| 通化县| 吉首市| 甘泉县| 绥棱县| 钟山县| 博乐市| 寿阳县| 凌源市| 横峰县|