欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文詳解Java對(duì)象的序列化和反序列化

 更新時(shí)間:2023年04月16日 10:21:38   作者:Cosolar  
本文主要介紹了一文詳解Java對(duì)象的序列化和反序列化,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

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

一、什么是 Java 序列化和反序列化?

Java 對(duì)象的序列化是將 Java 對(duì)象轉(zhuǎn)換成字節(jié)流的過程,可用于持久化數(shù)據(jù),傳輸數(shù)據(jù)等。序列化是將 Java 對(duì)象的狀態(tài)表示為字節(jié)序列的過程,可以通過網(wǎng)絡(luò)傳送,存儲(chǔ)到文件中或者使用其他的持久化技術(shù),如數(shù)據(jù)庫等。序列化后的字節(jié)流可以被傳輸給遠(yuǎn)程系統(tǒng),并在那里重新構(gòu)造成原始對(duì)象。Java 序列化是一個(gè)將對(duì)象轉(zhuǎn)化為字節(jié)流的過程。

Java 對(duì)象的反序列化是將字節(jié)流重新恢復(fù)為原始對(duì)象的過程。反序列化是將字節(jié)流轉(zhuǎn)化為對(duì)象的過程。反序列化是對(duì)象序列化的逆過程,通過反序列化操作能夠在接收端恢復(fù)出與發(fā)送端相同的對(duì)象。當(dāng)我們需要對(duì)存儲(chǔ)的對(duì)象進(jìn)行讀取操作時(shí),就需要對(duì)序列化的字節(jié)流進(jìn)行反序列化操作,將字節(jié)流轉(zhuǎn)化為原始的對(duì)象信息。

二、序列化和反序列化的實(shí)現(xiàn)方式

Java 中的序列化和反序列化可以通過實(shí)現(xiàn) Serializable 接口來完成。Serializable 是一種標(biāo)記接口,它沒有方法定義,但它具有一個(gè)特別的作用,就是用于在描述 java 類可序列化時(shí)做類型判斷的信息。當(dāng)一個(gè)類實(shí)現(xiàn) Serializable 接口時(shí),表明這個(gè)類是可序列化的。Serializable 接口只是一個(gè)標(biāo)識(shí)接口,我們并不需要重載任何方法。

在實(shí)現(xiàn) Serializable 接口后,就可以通過 ObjectOutputStream 來將對(duì)象序列化,并將序列化后的字節(jié)流輸出到文件或網(wǎng)絡(luò)中;同時(shí),也可以通過 ObjectInputStream 來將序列化后的字節(jié)流反序列化成對(duì)象。 java.io.ObjectOutputStream 繼承自 OutputStream 類,因此可以將序列化后的字節(jié)序列寫入到文件、網(wǎng)絡(luò)等輸出流中。

來看 ObjectOutputStream 的構(gòu)造方法: ObjectOutputStream(OutputStream out)

一個(gè)對(duì)象要想序列化,必須滿足兩個(gè)條件:

  • 該類必須實(shí)現(xiàn)java.io.Serializable 接口open in new window,否則會(huì)拋出NotSerializableException 。
  • 該類的所有字段都必須是可序列化的。如果一個(gè)字段不需要序列化,則需要使用transient 關(guān)鍵字open in new window進(jìn)行修飾。
  • 該構(gòu)造方法接收一個(gè) OutputStream 對(duì)象作為參數(shù),用于將序列化后的字節(jié)序列輸出到指定的輸出流中。

示例代碼如下:

import java.io.*;

public class SerializationDemo {
    public static void main(String[] args) {
        // 序列化對(duì)象
        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();
        }

        // 反序列化對(duì)象
        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 +
                '}';
    }
}

在上述代碼中,我們定義了一個(gè) Person 類,該類實(shí)現(xiàn)了 Serializable 接口。在序列化過程中,我們使用 ObjectOutputStream 類將 person 對(duì)象寫出到文件中;在反序列化過程中,我們使用 ObjectInputStream 類讀取文件中的字節(jié)流,并將其轉(zhuǎn)換為 Person 對(duì)象。

三、序列化和反序列化的注意事項(xiàng)

  • 私有化序列號(hào)屬性

序列化和反序列化需要使用對(duì)象的序列號(hào)屬性(serialVersionUID)來判斷版本號(hào)是否一致,從而防止在新版本和舊版本之間發(fā)生不兼容的情況。如果沒有顯式地聲明 serialVersionUID,則編譯器會(huì)自動(dòng)生成一個(gè) serialVersionUID,但這種方式是不可靠的,因?yàn)樵谛薷倪^程中可能會(huì)產(chǎn)生 serialVersionUID 的變化,從而導(dǎo)致不兼容問題。

因此,在 Java 序列化中,最好顯式地聲明 serialVersionUID 屬性,并進(jìn)行私有化,避免意外的修改。例如:

private static final long serialVersionUID = 1L;
  • 實(shí)現(xiàn) readObject 和 writeObject 方法

readObject 和 writeObject 是在序列化和反序列化過程中用于自定義序列化的方法。通常情況下,我們可以直接使用默認(rèn)的序列化方法,但是有時(shí)我們需要對(duì)序列化內(nèi)容進(jìn)行一些處理,這時(shí)就需要實(shí)現(xiàn) readObject 和 writeObject 方法。例如,對(duì)于對(duì)象中敏感數(shù)據(jù)的處理,我們可以在 writeObject 方法中對(duì)數(shù)據(jù)進(jìn)行加密處理,在 readObject 方法中解密處理。

需要注意的是,在實(shí)現(xiàn) readObject 和 writeObject 方法時(shí),必須要調(diào)用默認(rèn)方法,默認(rèn)方法可以通過 ObjectInputStream 和 ObjectOutputStream 類的 defaultReadObject 和 defaultWriteObject 方法調(diào)用。

四、序列化和反序列化的優(yōu)點(diǎn)和缺點(diǎn)

序列化和反序列化的優(yōu)點(diǎn)是:

  • 對(duì)象的序列化方便了對(duì)象在不同應(yīng)用之間的傳遞、存儲(chǔ)和恢復(fù)。

  • 通過序列化可以實(shí)現(xiàn)分布式計(jì)算,在不同的機(jī)器上對(duì)同一對(duì)象進(jìn)行操作和協(xié)作。

  • 序列化提供了數(shù)據(jù)持久化的能力,即將對(duì)象的狀態(tài)保存在硬盤等介質(zhì)中,下次可以直接從硬盤中讀取數(shù)據(jù),避免了頻繁地進(jìn)行數(shù)據(jù)庫讀寫操作。

序列化和反序列化的缺點(diǎn)是:

  • 在進(jìn)行序列化和反序列化操作時(shí),需要消耗額外的時(shí)間和開銷,特別是當(dāng)對(duì)象比較大或者嵌套較深的時(shí)候,可能會(huì)導(dǎo)致嚴(yán)重的性能問題。

  • 序列化和反序列化可能存在安全性問題,如果被攻擊者篡改了序列化后的字節(jié)流數(shù)據(jù),那么反序列化后的對(duì)象可能會(huì)出現(xiàn)意外行為,如獲得不應(yīng)該獲得的權(quán)限。

五、總結(jié)

Java 對(duì)象的序列化和反序列化是一種將對(duì)象轉(zhuǎn)換成字節(jié)流并存儲(chǔ)在硬盤或網(wǎng)絡(luò)中,以及從字節(jié)流中重新加載對(duì)象的操作。序列化和反序列化均需要實(shí)現(xiàn) Serializable 接口,并使用 ObjectOutputStream 和 ObjectInputStream 類來完成。序列化和反序列化可以方便地實(shí)現(xiàn)對(duì)象在不同應(yīng)用之間的傳遞、存儲(chǔ)和恢復(fù)等功能,但也存在一些缺點(diǎn),如可能會(huì)導(dǎo)致嚴(yán)重的性能問題和安全性問題。在使用過程中,需要根據(jù)具體的業(yè)務(wù)場(chǎng)景和需求進(jìn)行選擇和優(yōu)化,以達(dá)到最佳的效果。

在實(shí)際的 Java 開發(fā)中,序列化和反序列化是一個(gè)非常常見的操作,例如在分布式系統(tǒng)中,需要將對(duì)象序列化后通過網(wǎng)絡(luò)傳輸,在不同的機(jī)器上進(jìn)行反序列化以得到原始對(duì)象。

以下是一些使用序列化和反序列化的示例場(chǎng)景:

  • 緩存

在實(shí)際的開發(fā)中,我們經(jīng)常需要對(duì)一些數(shù)據(jù)進(jìn)行緩存,使用序列化可以將對(duì)象序列化為字節(jié)數(shù)組,然后將字節(jié)數(shù)組存儲(chǔ)到文件或者緩存中。當(dāng)需要使用緩存中的對(duì)象時(shí),再進(jìn)行反序列化操作,重新獲得原始對(duì)象。

  • 遠(yuǎn)程調(diào)用

在分布式系統(tǒng)中,需要將對(duì)象序列化后通過網(wǎng)絡(luò)傳輸,在不同的機(jī)器上進(jìn)行反序列化以得到原始對(duì)象。例如在 Dubbo 框架中,就使用了對(duì)象序列化和反序列化機(jī)制。

  • 持久化數(shù)據(jù)

在實(shí)際的開發(fā)中,我們需要將某些對(duì)象的狀態(tài)保存到數(shù)據(jù)庫或者文件中,使用序列化可以將對(duì)象序列化為字節(jié)數(shù)組,然后將字節(jié)數(shù)組存儲(chǔ)到數(shù)據(jù)庫或者文件中。當(dāng)需要讀取數(shù)據(jù)時(shí),再進(jìn)行反序列化操作,獲得原始對(duì)象。

一般使用 Java 序列化和反序列化只需要實(shí)現(xiàn) Serializable 接口即可,但是也可以使用一些工具依賴來簡(jiǎn)化操作。以下是一些常用的序列化和反序列化工具依賴:

1. Jackson

Jackson 是一個(gè)非常常用的序列化和反序列化工具,在 Spring Boot 等框架中也被廣泛使用。Jackson 可以將對(duì)象序列化為 JSON 或者 XML 格式,同時(shí)也可以將 JSON 或者 XML 反序列化為對(duì)象。

2. Gson

Gson 是另一個(gè)常用的序列化和反序列化工具,同樣可以將對(duì)象序列化為 JSON 格式,也可以將 JSON 反序列化為對(duì)象。

3. Protobuf

Protobuf 是 Google 開源的一種輕量級(jí)、高效、可擴(kuò)展的序列化框架,支持多種編程語言。與 Java 序列化相比,Protobuf 使用效率更高,序列化后的字節(jié)流更小,但需要預(yù)定義消息格式。

4. Kyro

Kryo 是一個(gè)高性能的 Java 序列化和反序列化工具,可以將 Java 對(duì)象序列化為字節(jié)數(shù)組,適合于網(wǎng)絡(luò)通信和數(shù)據(jù)持久化等場(chǎng)景。Kryo 能夠快速地序列化和反序列化 Java 對(duì)象,相對(duì)于 Java 自帶的序列化機(jī)制,它的速度更快,序列化后的字節(jié)數(shù)組也更小。

以上是一些常用的序列化和反序列化工具依賴,根據(jù)不同的業(yè)務(wù)需求和場(chǎng)景需要選擇適合的工具。

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

相關(guān)文章

  • java編程中字節(jié)流轉(zhuǎn)換成字符流的實(shí)現(xiàn)方法

    java編程中字節(jié)流轉(zhuǎn)換成字符流的實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄猨ava編程中字節(jié)流轉(zhuǎn)換成字符流的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-01-01
  • idea創(chuàng)建maven項(xiàng)目速度慢的三種解決方案

    idea創(chuàng)建maven項(xiàng)目速度慢的三種解決方案

    這篇文章主要介紹了idea創(chuàng)建maven項(xiàng)目速度慢的三種解決方案,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • SpringBoot中間件ORM框架實(shí)現(xiàn)案例詳解(Mybatis)

    SpringBoot中間件ORM框架實(shí)現(xiàn)案例詳解(Mybatis)

    這篇文章主要介紹了SpringBoot中間件ORM框架實(shí)現(xiàn)案例詳解(Mybatis),本篇文章提煉出mybatis最經(jīng)典、最精簡(jiǎn)、最核心的代碼設(shè)計(jì),來實(shí)現(xiàn)一個(gè)mini-mybatis,從而熟悉并掌握ORM框架的涉及實(shí)現(xiàn),需要的朋友可以參考下
    2023-07-07
  • Spring框架AOP面向切面編程原理全面分析

    Spring框架AOP面向切面編程原理全面分析

    這篇文章主要介紹了Spring框架AOP面向切面編程的全面分析,文中附含詳細(xì)的示例代碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-09-09
  • 淺談System.getenv()和System.getProperty()的區(qū)別

    淺談System.getenv()和System.getProperty()的區(qū)別

    這篇文章主要介紹了System.getenv()和System.getProperty()的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java List接口與Iterator接口及foreach循環(huán)使用解析

    Java List接口與Iterator接口及foreach循環(huán)使用解析

    這篇文章主要介紹了Java List接口與Iterator接口及foreach循環(huán),主要包括List接口與Iterator接口及foreach循環(huán)具體的使用方法和代碼,需要的朋友可以參考下
    2022-04-04
  • Java跳出多重嵌套循環(huán)代碼實(shí)例

    Java跳出多重嵌套循環(huán)代碼實(shí)例

    這篇文章主要介紹了Java跳出多重嵌套循環(huán),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Java?數(shù)據(jù)結(jié)構(gòu)與算法系列精講之漢諾塔

    Java?數(shù)據(jù)結(jié)構(gòu)與算法系列精講之漢諾塔

    漢諾塔是源于印度一個(gè)古老傳說的益智玩具。大梵天創(chuàng)造世界時(shí)做了三根石柱,在一根柱子上從下往上按大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。并且規(guī)定,在小圓盤上不能放大圓盤,三根柱子之間一次只能移動(dòng)一個(gè)圓盤
    2022-02-02
  • JAVA JSP頁面技術(shù)之EL表達(dá)式整理歸納總結(jié)

    JAVA JSP頁面技術(shù)之EL表達(dá)式整理歸納總結(jié)

    這篇文章主要介紹了java中JSP頁面技術(shù)之EL表達(dá)式概念作用以及語法等的使用,需要的朋友可以參考
    2017-04-04
  • Java之SpringBean生命周期問題理解

    Java之SpringBean生命周期問題理解

    這篇文章主要介紹了Java之SpringBean生命周期問題理解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07

最新評(píng)論