亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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、二進制格式等,以便可以在不同的系統(tǒng)或環(huá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ò)上傳輸。
  • 對象深拷貝:通過序列化一個對象,然后立即進行反序列化,可以實現(xiàn)對象的深拷貝。

反序列化(Deserialization)

反序列化是序列化的逆過程,即將序列化后的數(shù)據(jù)(如JSON、XML、二進制格式等)轉(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默認的序列化方式,通過實現(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ù)進行加密等。

3. 使用JSON序列化庫

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

4. 使用XML序列化庫

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

5. 使用二進制序列化庫

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

6. 其他序列化方式

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

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

Java默認序列化與反序列化示例

我們先將一些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));
        //讀?。捶葱蛄谢┑捻樞蛐枰捅4鏀?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,為了提高版本的兼容性。
  • 序列化對象時,默認將里面所有的屬性都進行序列化,除了stati、transient 修飾的成員。
  • 序列化對象時,要求里面屬性的類型也需要實現(xiàn)序列化接口。
  • 序列化具備可繼承性,也就是如果某類已經(jīng)實現(xià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ù)其序列化前的值。相反,它們會被初始化為默認值(例如,數(shù)值類型的變量會被初始化為0或false,對象類型的變量會被初始化為null)。因此,開發(fā)者需要在反序列化后,根據(jù)需要手動為這些變量賦值。

二者對比表格

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

總結(jié) 

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

相關(guān)文章

  • Java中Scanner的常用方法總結(jié)(一次學(xué)懂)

    Java中Scanner的常用方法總結(jié)(一次學(xué)懂)

    這篇文章主要給大家介紹了關(guān)于Java中Scanner常用方法的相關(guān)資料,Java中的Scanner是一個用于讀取用戶輸入的類,它可以讀取各種類型的數(shù)據(jù),包括整數(shù)、浮點數(shù)、字符串等等,需要的朋友可以參考下
    2023-11-11
  • SpringBoot如何使用mail實現(xiàn)登錄郵箱驗證

    SpringBoot如何使用mail實現(xiàn)登錄郵箱驗證

    在實際的開發(fā)當(dāng)中,不少的場景中需要我們使用更加安全的認證方式,同時也為了防止一些用戶惡意注冊,我們可能會需要用戶使用一些可以證明個人身份的注冊方式,如短信驗證、郵箱驗證等,這篇文章主要介紹了SpringBoot如何使用mail實現(xiàn)登錄郵箱驗證,需要的朋友可以參考下
    2024-06-06
  • java多線程Thread的實現(xiàn)方法代碼詳解

    java多線程Thread的實現(xiàn)方法代碼詳解

    這篇文章主要介紹了java多線程Thread的實現(xiàn)方法代碼詳解,涉及start(),run(),stop(),interrupt(),isInterrupted(),join()和join(long millis)等方法的介紹,具有一定借鑒價值,需要的朋友可以了解下。
    2017-11-11
  • java異步調(diào)用Feign接口空指針問題解決

    java異步調(diào)用Feign接口空指針問題解決

    這篇文章主要為大家介紹了java異步調(diào)用Feign接口空指針問題解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • SpringBoot集成Shiro進行權(quán)限控制和管理的示例

    SpringBoot集成Shiro進行權(quán)限控制和管理的示例

    這篇文章主要介紹了SpringBoot集成Shiro進行權(quán)限控制和管理的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • 解決springboot遇到autowire注入為null的問題

    解決springboot遇到autowire注入為null的問題

    這篇文章主要介紹了解決springboot遇到autowire注入為null的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • Eclipse創(chuàng)建JavaWeb工程的完整步驟記錄

    Eclipse創(chuàng)建JavaWeb工程的完整步驟記錄

    很多新手不知道Eclipse怎么創(chuàng)建Java Web項目,一起來看看吧,這篇文章主要給大家介紹了關(guān)于Eclipse創(chuàng)建JavaWeb工程的完整步驟,需要的朋友可以參考下
    2023-10-10
  • Java超詳細教你寫一個網(wǎng)絡(luò)購書系統(tǒng)案例

    Java超詳細教你寫一個網(wǎng)絡(luò)購書系統(tǒng)案例

    這篇文章主要介紹了怎么用Java來寫一個購書系統(tǒng),購買書籍主要需要每本書的編號、書名、單價、庫存屬性,能夠讓客戶通過編號來選書,感興趣的朋友跟隨文章往下看看吧
    2022-03-03
  • idea如何在service窗口中顯示多個服務(wù)

    idea如何在service窗口中顯示多個服務(wù)

    這篇文章主要介紹了idea如何在service窗口中顯示多個服務(wù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 如何基于SpringMVC實現(xiàn)斷點續(xù)傳(HTTP)

    如何基于SpringMVC實現(xiàn)斷點續(xù)傳(HTTP)

    這篇文章主要介紹了如何基于SpringMVC實現(xiàn)斷點續(xù)傳(HTTP),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01

最新評論