• Java中的序列化、反序列化-serializable和serialversionUID


    在Java项目中,我们经常对实体类进行implement serializable,在实体类中又加上一句

    private static final long serialVersionUID = 5177165015785112433L;

    最开始只知道是跟实体类的序列化有关,但是没有深究,昨天突然想起来了,于是想知道到底是什么东西,在这里小手一抖,记录一下......


    这里补充一下小知识:

      1、序列化、反序列化:

      序列化:将对象转化为字节序列的过程;

      反序列化:将字节序列反转成对象的过程。  具体看到下面的例子就明白了

      2、在io流中,有ObjectInputStream、ObjectoutputStream,这俩个在用在实体对象时,要求对象必须实现serializable,表示该对象可被序列化。

     一、首先我们尝试一下,实体类不进行implement Serializable,分别对实体类进行序列化和反序列化

      咱的实体类:

     1 package com.example.io.serializable;
     2 
     3 import lombok.Data;
     4 
     5 import java.io.Serializable;
     6 
     7 /**
     8  * @program: io
     9  * @description:
    10  * @author: liuqj
    11  * @create: 2020-06-17 09:41
    12  **/
    13 @Data
    14 public class Book {
    15 
    16     private int id;
    17     private String name;
    18     private Double price;
    19 }

     测试: 

     1     package com.example.io.serializable;
     2 
     3     import java.io.*;
     4 
     5     /**
     6      * @program: io
     7      * @description:
     8      * @author: liuqj
     9      * @create: 2020-06-17 09:43
    10      **/
    11     public class TestSerializable {
    12         public static void main(String[] args) throws IOException, ClassNotFoundException {
    13             serializable();
    14             deserializable();
    15     }
    16     static void serializable () throws IOException {
    17         Book book = new Book();
    18         book.setId(1);
    19         book.setName("从大爆炸到黑洞");
    20         book.setPrice(100.00);
    21         ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(new File("D:\Personal\JavaProject\io\serializable.txt")));
    22         outputStream.writeObject(book);
           outputStream.clouse();
    23 System.out.println("序列化成功"); 24 } 25 static void deserializable() throws IOException, ClassNotFoundException { 26 ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(new File("D:\Personal\JavaProject\io\serializable.txt"))); 27 Book book = (Book) inputStream.readObject();
           inputStream.clouse();
    28 System.out.println(book); 29 }

    运行结果:

     

     可以看到如果不对实体类进行implement Serializable,那么进行序列化的时候就会报错。

    二、对实体进行implement Serializable,但不加serialversionUID。

    1 @Data
    2 public class Book implements Serializable{
    3 
    4     private int id;
    5     private String name;
    6     private Double price;
    7 }

    1、直接进行序列化、反序列化

      运行结果:

       1 序列化成功 2 Book(id=1, name=从大爆炸到黑洞, price=100.0) 3 4 Process finished with exit code 0 

    2、先进行序列化,然后修改(删除)对象中的属性,再进行反序列化

     1 D:WorkJdkinjava.exe "-javaagent:D:WorkIdeaIntelliJ IDEA 2019.3.4libidea_rt.jar=54850:D:WorkIdeaIntelliJ IDEA 2019.3.4in" -Dfile.encoding=UTF-8 -classpath D:WorkJdkjrelibcharsets.jar;D:WorkJdkjrelibdeploy.jar;D:WorkJdkjrelibextaccess-bridge-64.jar;D:WorkJdkjrelibextcldrdata.jar;D:WorkJdkjrelibextdnsns.jar;D:WorkJdkjrelibextjaccess.jar;D:WorkJdkjrelibextjfxrt.jar;D:WorkJdkjrelibextlocaledata.jar;D:WorkJdkjrelibext
    ashorn.jar;D:WorkJdkjrelibextsunec.jar;D:WorkJdkjrelibextsunjce_provider.jar;D:WorkJdkjrelibextsunmscapi.jar;D:WorkJdkjrelibextsunpkcs11.jar;D:WorkJdkjrelibextzipfs.jar;D:WorkJdkjrelibjavaws.jar;D:WorkJdkjrelibjce.jar;D:WorkJdkjrelibjfr.jar;D:WorkJdkjrelibjfxswt.jar;D:WorkJdkjrelibjsse.jar;D:WorkJdkjrelibmanagement-agent.jar;D:WorkJdkjrelibplugin.jar;D:WorkJdkjrelib
    esources.jar;D:WorkJdkjrelib
    t.jar;D:PersonalJavaProjectio	argetclasses;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-starter-data-jdbc2.3.1.RELEASEspring-boot-starter-data-jdbc-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-starter-jdbc2.3.1.RELEASEspring-boot-starter-jdbc-2.3.1.RELEASE.jar;D:WorkMaven
    epositorycomzaxxerHikariCP3.4.5HikariCP-3.4.5.jar;D:WorkMaven
    epositoryorgspringframeworkspring-jdbc5.2.7.RELEASEspring-jdbc-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkdataspring-data-jdbc2.0.1.RELEASEspring-data-jdbc-2.0.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkdataspring-data-relational2.0.1.RELEASEspring-data-relational-2.0.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkdataspring-data-commons2.3.1.RELEASEspring-data-commons-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-tx5.2.7.RELEASEspring-tx-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-context5.2.7.RELEASEspring-context-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-aop5.2.7.RELEASEspring-aop-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-expression5.2.7.RELEASEspring-expression-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-beans5.2.7.RELEASEspring-beans-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgslf4jslf4j-api1.7.30slf4j-api-1.7.30.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-starter2.3.1.RELEASEspring-boot-starter-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot2.3.1.RELEASEspring-boot-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-autoconfigure2.3.1.RELEASEspring-boot-autoconfigure-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-starter-logging2.3.1.RELEASEspring-boot-starter-logging-2.3.1.RELEASE.jar;D:WorkMaven
    epositorychqoslogbacklogback-classic1.2.3logback-classic-1.2.3.jar;D:WorkMaven
    epositorychqoslogbacklogback-core1.2.3logback-core-1.2.3.jar;D:WorkMaven
    epositoryorgapachelogginglog4jlog4j-to-slf4j2.13.3log4j-to-slf4j-2.13.3.jar;D:WorkMaven
    epositoryorgapachelogginglog4jlog4j-api2.13.3log4j-api-2.13.3.jar;D:WorkMaven
    epositoryorgslf4jjul-to-slf4j1.7.30jul-to-slf4j-1.7.30.jar;D:WorkMaven
    epositoryjakartaannotationjakarta.annotation-api1.3.5jakarta.annotation-api-1.3.5.jar;D:WorkMaven
    epositoryorgyamlsnakeyaml1.26snakeyaml-1.26.jar;D:WorkMaven
    epositoryorgspringframeworkspring-core5.2.7.RELEASEspring-core-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-jcl5.2.7.RELEASEspring-jcl-5.2.7.RELEASE.jar com.example.io.serializable.TestSerializable
     2 Exception in thread "main" java.io.InvalidClassException: com.example.io.serializable.Book; 
        local class incompatible: stream classdesc serialVersionUID = -1858406188231479520, local class serialVersionUID = 4049423394988101590 3 at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616) 4 at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1843) 5 at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1713) 6 at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2000) 7 at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535) 8 at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422) 9 at com.example.io.serializable.TestSerializable.deserializable(TestSerializable.java:27) 10 at com.example.io.serializable.TestSerializable.main(TestSerializable.java:14) 11 12 Process finished with exit code 1

    可以看到反序列化失败,报错中显示,流中的UID和本地的UID不一致导致的反序列化失败,但我们本地并没有加serialversionUID啊?

    是酱紫滴,虽然我们没加,但是实现了implement Serializable,该接口会帮我们在本地生成一个UID,但这种默认生成的方式,在进行反序列化时不顶用了,

    会出现InvalidClassException异常,原因我也木知。(猜测大概是:序列化时(本地->流),会生成一次UID给到序列化后的内容中,反序列化时(流->本地)又再次生成了一次UID给本地,

    此时,流中的UID和新生成的本地UID不同,所以导致无法反序列化)

    三、实体类implement Serializable 且加上serialversionUID

    1 public class Book implements Serializable{
    2 
    3     private static final Long serialVersionUID = -1858406188231479520L;  //注意final不能少,不然本地的UID在反序列化的过程中会被更改,这句代码就相当于没加
    4     private int id;
    5     private String name;
    6     private Double price;
    7 }

    1、先直接进行序列化、反序列化

      结果显示:nice

    1 D:WorkJdkinjava.exe "-javaagent:D:WorkIdeaIntelliJ IDEA 2019.3.4libidea_rt.jar=55570:D:WorkIdeaIntelliJ IDEA 2019.3.4in" -Dfile.encoding=UTF-8 -classpath D:WorkJdkjrelibcharsets.jar;D:WorkJdkjrelibdeploy.jar;D:WorkJdkjrelibextaccess-bridge-64.jar;D:WorkJdkjrelibextcldrdata.jar;D:WorkJdkjrelibextdnsns.jar;D:WorkJdkjrelibextjaccess.jar;D:WorkJdkjrelibextjfxrt.jar;D:WorkJdkjrelibextlocaledata.jar;D:WorkJdkjrelibext
    ashorn.jar;D:WorkJdkjrelibextsunec.jar;D:WorkJdkjrelibextsunjce_provider.jar;D:WorkJdkjrelibextsunmscapi.jar;D:WorkJdkjrelibextsunpkcs11.jar;D:WorkJdkjrelibextzipfs.jar;D:WorkJdkjrelibjavaws.jar;D:WorkJdkjrelibjce.jar;D:WorkJdkjrelibjfr.jar;D:WorkJdkjrelibjfxswt.jar;D:WorkJdkjrelibjsse.jar;D:WorkJdkjrelibmanagement-agent.jar;D:WorkJdkjrelibplugin.jar;D:WorkJdkjrelib
    esources.jar;D:WorkJdkjrelib
    t.jar;D:PersonalJavaProjectio	argetclasses;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-starter-data-jdbc2.3.1.RELEASEspring-boot-starter-data-jdbc-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-starter-jdbc2.3.1.RELEASEspring-boot-starter-jdbc-2.3.1.RELEASE.jar;D:WorkMaven
    epositorycomzaxxerHikariCP3.4.5HikariCP-3.4.5.jar;D:WorkMaven
    epositoryorgspringframeworkspring-jdbc5.2.7.RELEASEspring-jdbc-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkdataspring-data-jdbc2.0.1.RELEASEspring-data-jdbc-2.0.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkdataspring-data-relational2.0.1.RELEASEspring-data-relational-2.0.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkdataspring-data-commons2.3.1.RELEASEspring-data-commons-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-tx5.2.7.RELEASEspring-tx-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-context5.2.7.RELEASEspring-context-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-aop5.2.7.RELEASEspring-aop-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-expression5.2.7.RELEASEspring-expression-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-beans5.2.7.RELEASEspring-beans-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgslf4jslf4j-api1.7.30slf4j-api-1.7.30.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-starter2.3.1.RELEASEspring-boot-starter-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot2.3.1.RELEASEspring-boot-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-autoconfigure2.3.1.RELEASEspring-boot-autoconfigure-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-starter-logging2.3.1.RELEASEspring-boot-starter-logging-2.3.1.RELEASE.jar;D:WorkMaven
    epositorychqoslogbacklogback-classic1.2.3logback-classic-1.2.3.jar;D:WorkMaven
    epositorychqoslogbacklogback-core1.2.3logback-core-1.2.3.jar;D:WorkMaven
    epositoryorgapachelogginglog4jlog4j-to-slf4j2.13.3log4j-to-slf4j-2.13.3.jar;D:WorkMaven
    epositoryorgapachelogginglog4jlog4j-api2.13.3log4j-api-2.13.3.jar;D:WorkMaven
    epositoryorgslf4jjul-to-slf4j1.7.30jul-to-slf4j-1.7.30.jar;D:WorkMaven
    epositoryjakartaannotationjakarta.annotation-api1.3.5jakarta.annotation-api-1.3.5.jar;D:WorkMaven
    epositoryorgyamlsnakeyaml1.26snakeyaml-1.26.jar;D:WorkMaven
    epositoryorgspringframeworkspring-core5.2.7.RELEASEspring-core-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-jcl5.2.7.RELEASEspring-jcl-5.2.7.RELEASE.jar com.example.io.serializable.TestSerializable
    2 序列化成功
    3 Book(id=1, name=从大爆炸到黑洞, price=100.0)
    4 
    5 Process finished with exit code 0

    2、先序列化,然后删除(修改)对象中某一个属性,再进行反序列化

      删除一个属性后的实体类

    1 @Data
    2 public class Book implements Serializable{
    3 
    4     private static final long serialVersionUID = -1858406188231479520L;
    5 
    6     private int id;
    7     private String name;
    8     //private Double price;
    9 }

      反序列化

    1 D:WorkJdkinjava.exe "-javaagent:D:WorkIdeaIntelliJ IDEA 2019.3.4libidea_rt.jar=56290:D:WorkIdeaIntelliJ IDEA 2019.3.4in" -Dfile.encoding=UTF-8 -classpath D:WorkJdkjrelibcharsets.jar;D:WorkJdkjrelibdeploy.jar;D:WorkJdkjrelibextaccess-bridge-64.jar;D:WorkJdkjrelibextcldrdata.jar;D:WorkJdkjrelibextdnsns.jar;D:WorkJdkjrelibextjaccess.jar;D:WorkJdkjrelibextjfxrt.jar;D:WorkJdkjrelibextlocaledata.jar;D:WorkJdkjrelibext
    ashorn.jar;D:WorkJdkjrelibextsunec.jar;D:WorkJdkjrelibextsunjce_provider.jar;D:WorkJdkjrelibextsunmscapi.jar;D:WorkJdkjrelibextsunpkcs11.jar;D:WorkJdkjrelibextzipfs.jar;D:WorkJdkjrelibjavaws.jar;D:WorkJdkjrelibjce.jar;D:WorkJdkjrelibjfr.jar;D:WorkJdkjrelibjfxswt.jar;D:WorkJdkjrelibjsse.jar;D:WorkJdkjrelibmanagement-agent.jar;D:WorkJdkjrelibplugin.jar;D:WorkJdkjrelib
    esources.jar;D:WorkJdkjrelib
    t.jar;D:PersonalJavaProjectio	argetclasses;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-starter-data-jdbc2.3.1.RELEASEspring-boot-starter-data-jdbc-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-starter-jdbc2.3.1.RELEASEspring-boot-starter-jdbc-2.3.1.RELEASE.jar;D:WorkMaven
    epositorycomzaxxerHikariCP3.4.5HikariCP-3.4.5.jar;D:WorkMaven
    epositoryorgspringframeworkspring-jdbc5.2.7.RELEASEspring-jdbc-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkdataspring-data-jdbc2.0.1.RELEASEspring-data-jdbc-2.0.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkdataspring-data-relational2.0.1.RELEASEspring-data-relational-2.0.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkdataspring-data-commons2.3.1.RELEASEspring-data-commons-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-tx5.2.7.RELEASEspring-tx-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-context5.2.7.RELEASEspring-context-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-aop5.2.7.RELEASEspring-aop-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-expression5.2.7.RELEASEspring-expression-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-beans5.2.7.RELEASEspring-beans-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgslf4jslf4j-api1.7.30slf4j-api-1.7.30.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-starter2.3.1.RELEASEspring-boot-starter-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot2.3.1.RELEASEspring-boot-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-autoconfigure2.3.1.RELEASEspring-boot-autoconfigure-2.3.1.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkootspring-boot-starter-logging2.3.1.RELEASEspring-boot-starter-logging-2.3.1.RELEASE.jar;D:WorkMaven
    epositorychqoslogbacklogback-classic1.2.3logback-classic-1.2.3.jar;D:WorkMaven
    epositorychqoslogbacklogback-core1.2.3logback-core-1.2.3.jar;D:WorkMaven
    epositoryorgapachelogginglog4jlog4j-to-slf4j2.13.3log4j-to-slf4j-2.13.3.jar;D:WorkMaven
    epositoryorgapachelogginglog4jlog4j-api2.13.3log4j-api-2.13.3.jar;D:WorkMaven
    epositoryorgslf4jjul-to-slf4j1.7.30jul-to-slf4j-1.7.30.jar;D:WorkMaven
    epositoryjakartaannotationjakarta.annotation-api1.3.5jakarta.annotation-api-1.3.5.jar;D:WorkMaven
    epositoryorgyamlsnakeyaml1.26snakeyaml-1.26.jar;D:WorkMaven
    epositoryorgspringframeworkspring-core5.2.7.RELEASEspring-core-5.2.7.RELEASE.jar;D:WorkMaven
    epositoryorgspringframeworkspring-jcl5.2.7.RELEASEspring-jcl-5.2.7.RELEASE.jar com.example.io.serializable.TestSerializable
    2 Book(id=1, name=从大爆炸到黑洞)
    3 
    4 Process finished with exit code 0

     总结:

    (1)对实体进行implement Serializable,表示该对象可以进行序列化;

    (2)只进行implement Serializable,每次进行序列化时会自动生成一个serialVersionUID保证序列化的进行,

      在实体对象没有改变过的前提下,可以进行反序列化,如果对象属性改变过,反序列化时再次生成的UID和序列化时生成的UID不同无法进行反序列化;

    (3)在进行implement Serializable后,加上private static final long serialVersionUID = xxxL; 可保证序列化之后,即使对实体对象做出了改变仍可以进行反序列化。

    乾坤未定,你我皆是黑马
  • 相关阅读:
    线性回归和 逻辑回归 的思考(参考斯坦福 吴恩达的课程)
    数据结构算法基础-内部排序算法
    机器学习《test》
    day1.接口测试(概念、Postman、SoapUI、jmeter)
    SQL2000 3核6核 CUP 安装SP4
    SQL常用语句
    SQL SERVER 2000数据库置疑处理
    常用终端命令
    c++ 位操作
    计算机为什么用补码存储数据?
  • 原文地址:https://www.cnblogs.com/liuqijia/p/13151288.html
Copyright © 2020-2023  润新知