zoukankan      html  css  js  c++  java
  • 序列化

    什么是序列化:

    序列化将对象转化成可以存储或者传输的状态,是处理对象流的机制,将对象流化,用于读写保存或者网络传输。

    如何序列化:

    实现serializable接口,  表示此类可以序列化,然后用一个输出流实现一个对象流(ObjectOutputStream),用于输出对象。

    声明serialVersionUID可以使类没有变化或者变化较小的情况下反序列化成功。

    序列化Serializable的方式特别简单 实现Serializable接口,再在类中声明如下这一个属性即可。

    private static final long serialVersionUID = -3928832861296252415L;

    Serializable序列化的工作机制:

    序列化的时候系统会把当前类的serialVersionUID 写入序列化的文件中(也可能是其他中介),当反序列化的时候系统会去检测文件中的serialVersionUID ,看它是否和当前类的serialVersionUID 一致,如果一致就说明序列化的类的版本和当前类的版本是相同的,这个时候可以成功反序列化,否则就说明当前类和序列化的类相比发生了某些变换,比如成员变量的数量,类型可能发生了改变,这个时候就会抛异常,反序列化失败。

    那么serialVersionUID 是如何生成,生成规则是怎么样的呢?

    默认情况下,也就是不声明serialVersionUID 属性情况下,系统会按当前类的成员变量计算hash值并赋值给serialVersionUID 。

    所以,结论就出来了。声明serialVersionUID ,可以很大程度上避免反序列化过程的失败。比如当版本升级后,我们可能删除了某个成员变量,也可能增加了一些新的成员变量,这个时候我们的反序列化依然能够成功,程序依然能够最大程度地恢复数据,相反,如果不指定serialVersionUID ,程序就会挂掉。

    如果类结构发生了非常规性改变,比如修改了类名,类型等,这个时候尽管serialVersionUID 验证通过了,但是反序列化过程

    还是会失败,因为类结构有了毁灭性的改变。

    2、串行化的特点:

        (1)如果某个类能够被串行化,其子类也可以被串行化。如果该类有父类,则分两种情况来考虑,如果该父类已经实现了可串行化接口。则其父类的相应字段及属性的处理和该类相同;如果该类的父类没有实现可串行化接口,则该类的父类所有的字段属性将不会串行化。

      (2)声明为static和transient类型的成员数据不能被串行化。因为static代表类的状态, transient代表对象的临时数据

    对于父类的处理,如果父类没有实现串行化接口,则其必须有默认的构造函数(即没有参数的构造函数)。否则编译的时候就会报错。在反串行化的时候,默认构造函数会被调用。但是若把父类标记为可以串行化,则在反串行化的时候,其默认构造函数不会被调用。这是为什么呢?这是因为Java 对串行化的对象进行反串行化的时候,直接从流里获取其对象数据来生成一个对象实例,而不是通过其构造函数来完成。

  • 相关阅读:
    Dubbo监控中心
    Dubbo 提供者配置&测试
    IDEA中pom.xml依赖另一个项目
    MBG
    查询优化技术之多级缓存
    分布式扩展流程
    Redis取值时取出的是HashMap
    linux执行sql
    Git的使用
    405
  • 原文地址:https://www.cnblogs.com/wuer888/p/7686301.html
Copyright © 2011-2022 走看看