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

Java序列化之serialVersionUID的用法解讀

 更新時(shí)間:2025年11月21日 10:46:24   作者:紅提口味趣多多  
Java序列化之serialVersionUID:本文介紹了Java對象的序列化和反序列化過程,強(qiáng)調(diào)了serialVersionUID的作用,以及如何生成和使用它來保證版本兼容性,通過實(shí)例代碼,展示了序列化和反序列化的具體操作

Java序列化之serialVersionUID

今天講一講Java對象中的serialVersionUID,先從序列化講起。

什么是序列化

序列化,簡單的說,就是將一個(gè)對象轉(zhuǎn)化(編碼)成可以傳輸?shù)妮敵隽鳎ㄗ止?jié)流)。而反序列化就是序列化的逆過程,將輸入流轉(zhuǎn)化(構(gòu)建)成一個(gè)對象。

為什么要序列化

字節(jié)流可以用于網(wǎng)絡(luò)傳輸和存儲在磁盤,而對象需要轉(zhuǎn)化成字節(jié)流才能在網(wǎng)絡(luò)中傳輸和在磁盤上存儲。

網(wǎng)絡(luò)傳輸就好比打電話,聲音是無法直接從電話的一端傳到另一端,因此需要將聲音轉(zhuǎn)成電信號進(jìn)行傳播。

另一方面,Java對象是保存在JVM的堆內(nèi)存中的,也就是說,如果JVM堆不存在了,那么對象也就跟著消失了,而序列化提供了可以把對象保存下來的方案。

serialVersionUID是個(gè)啥

說到序列化,serialVersionUID是個(gè)不得不談的話題。

serialVersionUID 是 Java 為每個(gè)序列化類(實(shí)現(xiàn)java.io.Serializable接口的類)產(chǎn)生的版本標(biāo)識, 可用來保證在反序列時(shí),發(fā)送方發(fā)送的和接受方接收的是可兼容的對象。

如果接收方接收的類的 serialVersionUID 與發(fā)送方發(fā)送的 serialVersionUID 不一致,進(jìn)行反序列時(shí)會拋出 InvalidClassException。

怎么生成serialVersionUID

下載GenerateSerialVersionUID插件,就可以自動(dòng)生產(chǎn)這個(gè)序列類的serialVersionUID了。

serialVersionUID是一成不變的嗎

達(dá)咩! 

serialVersionUID 是 Java 為每個(gè)序列化類產(chǎn)生的版本標(biāo)識!!

Java序列化機(jī)制會根據(jù)編譯的Class自動(dòng)生成一個(gè)serialVersionUID作序列化版本比較用。

如果Class文件的類名、方法名稱發(fā)生改變,serialVersionUID就會改變。

如果Class文件沒有發(fā)生變化(增加空格,換行,增加注釋等等),就算再編譯多次,serialVersionUID也不會變化的。

import java.io.Serializable;

public class Person implements Serializable {
    // 原本的serialVersionUID
    private static final long serialVersionUID = 904XXXXXXXXXX662L;

    private int age;
    private String name;
    private String address;

    public Person(int age, String name, String address) {
        this.age = age;
        this.name = name;
        this.address = address;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
}

import java.io.Serializable;

public class Person implements Serializable {
    // 加上toSting函數(shù)的serialVersionUID
    private static final long serialVersionUID = 841XXXXXXXXXXXXX884L;

    private int age;
    private String name;
    private String address;

    public Person(int age, String name, String address) {
        this.age = age;
        this.name = name;
        this.address = address;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

如果我手動(dòng)改了serialVersionUID=11111111L會怎樣?如果接收方接收的類的 serialVersionUID 與發(fā)送方發(fā)送的 serialVersionUID 不一致,進(jìn)行反序列時(shí)會拋出 InvalidClassException。

Exception in thread "main" java.io.InvalidClassException: SerializableStudy.Person; local class incompatible: stream classdesc serialVersionUID = 841XXXXXXXXXXXXX884, local class serialVersionUID = 11111111

序列化和反序列化

序列化要把對象寫入輸出流中,反序列化就是將輸出流重新構(gòu)建對象,二者為逆過程。當(dāng)serialVersionUID改變時(shí),一定要重新序列化,再進(jìn)行反序列化。

話不多說,放代碼。

以下是基于上面序列化類Person,做序列化和反序列化的演示:

public class SerialTest {

    public static void main(String[] args) throws IOException {
//        序列化
        Person p = new Person(0,"aaa","bbbbb");
//        指定文件生成輸出流
        FileOutputStream fos = new FileOutputStream("person.txt");
//        將對象寫出到指定的輸出流
        ObjectOutputStream oos = new ObjectOutputStream(fos);
//        將指定的對象寫入ObjectOutputStream。
        oos.writeObject(p);
//        刷新流
        oos.flush();
        oos.close();
    }
}
public class DeserialTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
//        反序列化
//        根據(jù)指定文件生產(chǎn)輸入流
        FileInputStream fis = new FileInputStream("person.txt");
//        從指定的輸入流中讀回對象消息
        ObjectInputStream ois = new ObjectInputStream(fis);
//        從ObjectInputStream讀取一個(gè)對象
        Person p = (Person) ois.readObject();
        ois.close();
        System.out.println(p.toString());
    }
}

輸出的結(jié)果為:

注意:

將指定對象寫入ObjectOutputStream時(shí),存儲針對對象本身而不是針對類,沒有實(shí)現(xiàn)序列化的類不會參與序列化和反序列化?。?/p>

舉個(gè)例子,如果Person中設(shè)置一個(gè)沒有實(shí)現(xiàn)序列化的父類Home:

public class Home {
    private String home;

    public String getHome() {
        return home;
    }

    public void setHome(String home) {
        this.home = home;
    }
}
public class Person extends Home implements Serializable {
	......
}

在序列化和反序列化的過程中,即使定義了Person對象的home屬性,由于Home中沒有實(shí)現(xiàn)序列類,因此對象的home屬性不會進(jìn)行序列化處理。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot如何切換成其它的嵌入式Servlet容器(Jetty和Undertow)

    SpringBoot如何切換成其它的嵌入式Servlet容器(Jetty和Undertow)

    這篇文章主要介紹了SpringBoot如何切換成其它的嵌入式Servlet容器(Jetty和Undertow),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • RocketMQ?NameServer架構(gòu)設(shè)計(jì)啟動(dòng)流程

    RocketMQ?NameServer架構(gòu)設(shè)計(jì)啟動(dòng)流程

    這篇文章主要為大家介紹了RocketMQ?NameServer架構(gòu)設(shè)計(jì)啟動(dòng)流程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Spring中循環(huán)依賴的解決方法詳析

    Spring中循環(huán)依賴的解決方法詳析

    這篇文章主要給大家介紹了關(guān)于Spring中循環(huán)依賴的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用spring具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • java 數(shù)據(jù)的加密與解密普遍實(shí)例代碼

    java 數(shù)據(jù)的加密與解密普遍實(shí)例代碼

    本篇文章介紹了一個(gè)關(guān)于密鑰查詢的jsp文件簡單實(shí)例代碼,需要的朋友可以參考下
    2017-04-04
  • MyBatis執(zhí)行SQL查詢的完整流程

    MyBatis執(zhí)行SQL查詢的完整流程

    本文詳細(xì)介紹了MyBatis SQL執(zhí)行的完整過程,包括核心對象、代碼實(shí)現(xiàn)與執(zhí)行鏈路,通過編程式調(diào)用示例和流程圖,展示了從環(huán)境配置、SqlSession創(chuàng)建到結(jié)果獲取的全步驟,需要的朋友可以參考下
    2026-01-01
  • Spring Security 在 Spring Boot 中的使用詳解【集中式】

    Spring Security 在 Spring Boot 中的使用詳解【集中式】

    這篇文章主要介紹了Spring Security 在 Spring Boot 中的使用【集中式】,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • java基于servlet實(shí)現(xiàn)文件上傳功能解析

    java基于servlet實(shí)現(xiàn)文件上傳功能解析

    這篇文章主要為大家詳細(xì)介紹了java基于servlet實(shí)現(xiàn)上傳功能,后臺使用java實(shí)現(xiàn),前端主要是js的ajax實(shí)現(xiàn),感興趣的小伙伴們可以參考一下
    2016-05-05
  • SpringBoot中@Value獲取值和@ConfigurationProperties獲取值用法及比較

    SpringBoot中@Value獲取值和@ConfigurationProperties獲取值用法及比較

    在Spring Boot中,@Value注解是一個(gè)非常有用的特性,它允許我們將外部的配置注入到我們的Bean中,@ConfigurationProperties用于將配置文件中的屬性綁定到 Java Bean 上,本文介紹了@Value獲取值和@ConfigurationProperties獲取值用法及比較,需要的朋友可以參考下
    2024-08-08
  • Java單測void類型的方法詳解

    Java單測void類型的方法詳解

    這篇文章主要給大家介紹了Java中單測void類型的方法,文中給出了詳細(xì)的示例代碼,相信對大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,需要的朋友可以跟著小編下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-01-01
  • Spring MVC傳遞接收參數(shù)方式小結(jié)

    Spring MVC傳遞接收參數(shù)方式小結(jié)

    大家在開發(fā)中經(jīng)常會用到Spring MVC Controller來接收請求參數(shù),主要常用的接收方式就是通過實(shí)體對象以及形參等方式、有些用于GET請求,有些用于POST請求,有些用于兩者,下面介紹幾種常見的Spring MVC傳遞接收參數(shù)的方式
    2021-11-11

最新評論

梨树县| 泽库县| 香河县| 永平县| 白水县| 阿瓦提县| 九台市| 肃宁县| 绥江县| 巴东县| 乐清市| 峨山| 潼关县| 武夷山市| 锦州市| 景泰县| 铜梁县| 青阳县| 城市| 兴宁市| 长宁区| 陆良县| 镇江市| 大新县| 木里| 上犹县| 临汾市| 恩平市| 八宿县| 宿州市| 来宾市| 靖州| 土默特左旗| 岗巴县| 涿州市| 徐州市| 郴州市| 攀枝花市| 房山区| 杨浦区| 三明市|