java学习---序列化

目录

  • 序列化和反序列化
  • 用途
  • java实现流程
  • java实现demo
    • 序列化对象
    • 序列化工具接口
    • 序列化实现类
    • 测试类
  • java序列化优缺点
  • 相关介绍
    • serialVersionUID 的作用
    • serialVersionUID生成方式
    • 静态变量序列化
    • 父类的序列化
    • Transient 关键字
  • 序列化算法优劣的两个指标
  • 其他序列化方式
    • XML 序列化框架
    • JSON 序列化框架
    • Hessian 序列化框架
    • Protobuf 序列化框架

1. 序列化和反序列化

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

2. 用途

  • 把对象的字节序列永久地保存到硬盘上
  • 在网络上传送对象的字节序列

3. java实现流程

  • 对象实现java.io.Serializable接口
  • 输出流:java.io.ObjectOutputStream
  • 输入流:java.io.ObjectInputStream

4. java实现demo

4.1 序列化对象

public class User implements Serializable {
    private String userName;
    private String age;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getAge() {
        return age;
    }

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

4.2 序列化工具接口

/**
 - @program: concurrent
 - @description: 序列化接口
 - @author: chengqj
 - @create: 2019-01-03 16:37
 **/
public interface ISerializer {
    /**
     * 序列化方法
     * @param obj 序列化对象
     * @param <T>
     * @return
     */
    <T> byte[] serialize(T obj);

    /**
     * 反序列化方法
     * @param data 反序列化数据
     * @param clazz 反序列化类
     * @param <T>
     * @return
     */
    <T> T deserialize(byte[] data,Class<T> clazz);
}

4.3 序列化实现类

public class JavaSerializer implements ISerializer{
    @Override
    public <T> byte[] serialize(T obj) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(obj);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return byteArrayOutputStream.toByteArray();
    }

    @Override
    public <T> T deserialize(byte[] data, Class<T> clazz) {
        ByteArrayInputStream byteArrayOutputStream = new ByteArrayInputStream(data);
        try {
            ObjectInputStream objectOutputStream = new ObjectInputStream(byteArrayOutputStream);
            return (T)objectOutputStream.readObject();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

4.4 测试类

public static void main(String[] args) {
    User user = new User();
    user.setAge("12");
    user.setUserName("名称");
    ISerializer serializer = new JavaSerializer();
    //实现序列化
    byte[] data = serializer.serialize(user);
    //反序列化
    User serialUser = serializer.deserialize(data,User.class);
    System.out.println(serialUser.getUserName());
}

5. java序列化优缺点

  • 优点:JAVA 语言本身提供,使用比较方便和简单
  • 缺点:不支持跨语言处理、 性能相对不是很好,序列化以后产生的数据相对较大

5. 相关介绍

5.1 serialVersionUID 的作用

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

5.2 serialVersionUID生成方式

  • 是默认的1L,比如:private static final long serialVersionUID = 1L;
  • 是根据类名、接口名、成员方法及属性等来生成一个64 位的哈希字段
  • 当没有显示指定的时候,java 序列化机制会根据编译的Class 自动生成一个serialVersionUID 作序列化版本

5.3 静态变量序列化

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

5.4 父类的序列化

  • 当一个父类没有实现序列化时,子类继承该父类并且实现了序列化。在反序列化该子类后,是没办法获取到父类的属性值的
  • 当一个父类实现序列化,子类自动实现序列化,不需要再显示实现Serializable 接口
  • 当一个对象的实例变量引用了其他对象,序列化该对象时也会把引用对象进行序列化,但是前提是该引用对象必须实现序列化接口

5.5 Transient 关键字

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

6. 序列化算法优劣的两个指标

  • 序列化以后的数据大小
  • 序列化操作本身的速度及系统资源开销(CPU、内存)

7. 其他序列化方式

7.1 XML 序列化框架

XML 序列化的好处在于可读性好,方便阅读和调试。但是序列化以后的字节码文件比较大,而且效率不高,适用于对性能不高,而且QPS 较低的企业级内部系统之间的数据交换的场景,同时XML 又具有语言无关性,所以还可以用于异构系统之间的数据交换和协议。比如我们熟知的Webservice,就是采用XML 格式对数据进行序列化的

7.2 JSON 序列化框架

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,相对于XML 来说,JSON的字节流更小,而且可读性也非常好。现在JSON数据格式在企业运用是最普遍的

7.3 Hessian 序列化框架

Hessian 是一个支持跨语言传输的二进制序列化协议,相对于Java 默认的序列化机制来说,Hessian 具有更好的性能和易用性,而且支持多种
不同的语言

实际上Dubbo 采用的就是Hessian 序列化来实现,只不过Dubbo 对Hessian 进行了重构,性能更高

7.4 Protobuf 序列化框架

Protobuf 是Google 的一种数据交换格式,它独立于语言、独立于平台。Google提供了多种语言来实现,比如Java、C、Go、Python,每一种实现都包含了相应语言的编译器和库文件
Protobuf 使用比较广泛,主要是空间开销小和性能比较好,非常适合用于公司内部对性能要求高的RPC 调用。 另外由于解析性能比较高,序列化以后数据量相对较少,所以也可以应用在对象的持久化场景中但是但是要使用Protobuf会相对来说麻烦些,因为他有自己的语法,有自己的编译器


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值