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

    参考文档:
    序列化与反序列化:http://kb.cnblogs.com/page/515982/
    jdk中的序列化api:http://blog.csdn.net/abc6368765/article/details/51365838
    jdk中如何序列化:http://www.cnblogs.com/redcreen/articles/1955307.html

    什么是序列化&为什么要序列化
    序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象

    主流序列化框架

    按照序列化后的数据格式,主流的序列化框架主要可以分为四大类:
    JSON类

    非常流行的Jackson
    Google的Gson。 Gson是目前功能最全的Json解析神器,无依赖,直接跑在jdk上。性能稍逊于fastjson
    类JSON的MessagePack
    阿里的FastJSON性能最好。无依赖,不需要例外额外的jar,能够直接跑在JDK上

    二进制类

    老牌劲旅Hessian(以前很喜欢用的)
    功能全面而强大的FST
    后起之秀Kryo

    XML类

    StAX(Streaming API for XML)
    Thoughwork的XStream

    RPC类(都要安装、编译)

    Protobuf
    Thrift
    Apache Avro 

    判断一个编码框架的优劣主要从以下几个方面

    1. 是否支持跨语言,支持语种是否丰富
    2. 编码后的码流存储空间
    3. 编解码的性能
    4. 类库是否小巧,API使用是否方便

    java序列化的缺点

    1. 无法跨语言。这应该是java序列化最致命的问题了。由于java序列化是java内部私有的协议,其他语言不支持,导致别的语言无法反序列化,这严重阻碍了它的应用
    2. 序列后的码流太大。java序列化的大小是二进制编码的5倍多
    3. 序列化性能太低。java序列化的性能只有二进制编码的6.17倍

    jdk类库中的序列化api

    序列化的实现

    只有实现了SerializableExternalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式
    ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中
    ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回

    serialVersionUID的作用

    s​e​r​i​a​l​V​e​r​s​i​o​n​U​I​D​:​ ​字​面​意​思​上​是​序​列​化​的​版​本​号​,凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量
    serialVersionUID有两种生成方式:

    serialVersionUID是1L
    private static final long serialVersionUID = 1L;
    在可兼容的前提下,可以保留旧版本号,如果不兼容,或者想让它不兼容,就手工递增版本号。

    serialVersionUID是依据类名,接口名,方法和属性等来生成的hash值:
    private static final long serialVersionUID = 4603642343377807741L;
    是根据类的结构产生的hash值。增减一个属性、方法等,都可能导致这个值产生变化。我想这种方式适用于这样的场景:开发者认为每次修改类后就需要生成新的版本号,不想向下兼容,操作就是删除原有serialVesionUid声明语句,再自动生成一下

    举例:
    User类序列到到kafka中,如果不指定serialVersionUID,该user类新增加了一个age属性,在反序列化的时候,则会抛出异常,拒绝载入。是因为改动user类以后,生成了一个新的serialVersionUID,与存储在kafka中的已经序列化的serialVersionUID版本不一致。所以反序列化发生冲突

    静态变量序列化

    序列化保存的是对象的状态,静态变量属于类的状态,因此序列化并不保存静态变量

    父类的序列化

    父类实现接口后,所有派生类的属性都会被序列化。子类实现接口的话,父类的属性值丢失

    Transient关键字

    Transient关键字的作用是控制变量的序列话,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null

  • 相关阅读:
    Cookie
    JS开发常用工具函数
    手动搭建Vue之前奏:搭建webpack项目
    Redis的下载与安装
    Redis官方Tutorial
    Redis之datatype概述
    18 SQL优化
    16 SQL Mode
    17 MySQL的小技巧
    14 事务控制和锁定语句
  • 原文地址:https://www.cnblogs.com/amei0/p/8480260.html
Copyright © 2011-2022 走看看