java序列化

参考链接:

  https://blog.csdn.net/xlgen157387/article/details/79840134?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

  https://blog.csdn.net/u013870094/article/details/82765907?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

问题:

  1.什么叫序列化和反序列化?

  2.作用。为啥要实现这个 Serializable 接口,也就是为啥要序列化?

  3.serialVersionUID 这个的值到底是在怎么设置的,有什么用。有的是1L,有的是一长串数字?

注意:java序列化Serializable接口,以及相关的东西,全部都在 Java io 里面的。

(1)序列化和反序列化的概念

  序列化:把对象转换为字节序列的过程称为对象的序列化。

  反序列化:把字节序列恢复为对象的过程称为对象的反序列化。

  本质上讲,序列化就是把实体对象状态按照一定的格式写入到有序字节流,反序列化就是从有序字节流重建对象,恢复对象状态。

(2)为什么要实现序列化

  当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等, 而这些数据都会以二进制序列的形式在网络上传送。

  那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?答案是可以的!如何做到呢?这就需要Java序列化与反序列化了!

  好处1:是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里);

  好处2:利用序列化实现远程通信,即在网络上传送对象的字节序列。

  总结:永久性保存对象,保存对象的字节序列到本地文件或者数据库中;

     通过序列化以字节流的形式使对象在网络中进行传递和接收;

     通过序列化在进程间传递对象;

(3)如何实现序列化(实现Serializable接口即可)

  a:java.io.ObjectOutputStream:表示对象输出流;它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中;

  b:java.io.ObjectInputStream:表示对象输入流;它的readObject()方法源输入流中读取字节序列,再把它们反序列化成为一个对象,并将其返回;

(4)serialVersionUID解析

  序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致 InvalidClassException。

  通俗的讲:Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。

  序列化操作的时候系统会把当前类的serialVersionUID写入到序列化文件中,当反序列化时系统会去检测文件中的serialVersionUID,判断它是否与当前类的serialVersionUID一致,如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。

  serialVersionUID的两种显示生成方式(序列化时为了保持版本的兼容性):

  1:是默认的1L,比如:private static final long serialVersionUID = 1L;  

  2:二是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:private static final  long   serialVersionUID = xxxxL;   

posted on 2020-03-18 12:07  hdc520  阅读(158)  评论(0编辑  收藏  举报

导航