把对象按照一定的协议格式序列化为数据流,这样用于存储或传输对象。本文主要介绍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
网友评论