JAVA原生序列化协议

把对象按照一定的协议格式序列化为数据流,这样用于存储或传输对象。本文主要介绍JAVA原生的序列化协议。

序列化类别

文本序列化和二进制序列化

文本序列化

常用的文本序列化方式:XML、JSON等。文本序列化协议最大的优势在于可读性强和跨语言强。缺点也是显而易见的,效率低。

二进制序列化

  • Protocol Buffers
  • Thrift
  • Java序列化
    可读性差,但高效。

JDK

JDK1.1起, sun就有Java Object Serialization Specification定义java的序列化方式。

class List implements java.io.Serializable {
    int value;
    List next;
    public static void main(String[] args) {
        try {
            List list1 = new List();
            List list2 = new List();
            list1.value = 17;
            list1.next = list2;
            list2.value = 19;
            list2.next = null;

            ByteArrayOutputStream o = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(o);
            out.writeObject(list1);
            out.writeObject(list2);
            out.flush();
            ...
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

把二进制写入文件后,可以用编辑器或者在Linux命令下使用hexdump查看文件。

00: ac ed 00 05 73 72 00 04 4c 69 73 74 69 c8 8a 15
10: 40 16 ae 68 02 00 02 49 00 05 76 61 6c 75 65 4c
20: 00 04 6e 65 78 74 74 00 06 4c 4c 69 73 74 3b 78
30: 70 00 00 00 11 73 71 00 7e 00 00 00 00 00 13 70
40: 71 00 7e 00 03

序列化文件头

ac ed :STREAM_MAGIC声明使用了序列化协议
00 05 :STREAM_VERSION序列化协议版本
73 :TC_OBJECT声明这是一个新的对象

注意事项

虽然Java的序列化能够保证对象状态的持久保存,但是遇到一些对象结构复杂的情况还是比较难处理的,下面是对一些复杂情况的总结:

  • 当父类实现了Serializable接口的时候,所有的子类都能序列化
  • 子类实现了Serializable接口,父类没有,父类中的属性不能被序列化(不报错,但是数据会丢失)
  • 如果序列化的属性是对象,对象必须也能序列化,否则会报错
  • 反序列化的时候,如果对象的属性有修改或则删减,修改的部分属性会丢失,但是不会报错
  • 在反序列化的时候serialVersionUID被修改的话,会反序列化失败
  • 在存Java环境下使用Java的序列化机制会支持的很好,但是在多语言环境下需要考虑别的序列化机制,比如xml,json,或则protobuf

参考(https://www.cnblogs.com/senlinyang/p/8204752.html)

你可能感兴趣的:(JAVA原生序列化协议)