Java序列化机制


Java序列化机制的主要目的是将内存中的对象转换成字节流,然后传输到其它的系统,并在其它系统中将字节流重新生成对象。典型的应用场景就是Java分布式系统,在一个JVM中创建的对象经常要通过网络等传输到另外一个JVM中。因此在Java分布式中,序列化是非常重要的一环。

Java语言提供序列化对象方式有两种:

实现 Serializable接口;这是系统的默认实现

实现 Externalizable,并实现其中的writeExternal(ObjectOutput out) 和 readExternal(ObjectInput in)方法。

Java序列化的规则 一个对象实现Serializable接口时,便具备了序列化的能力。但是查看Serializable接口的源码时,却会发现它是一个空接口,也就是说它只是标识作用,这与Java 1.5产生的Annotation功能类似。那JVM的默认序列化机制是怎么工作的呢?

其实Java语言本身定义序列化的规则:

类必须实现Serializable接口,或其父类实现了Serializable接口。

当一个对象被序列化时,从当前类开始的整个父级继承链上的对象都会被序列化,直到第一个没有实现Serializable接口的类O。如果该类没有继承关系,这个O就是是Object类。 规则1中的类O,必须包含一个无参数的构造函数。

在反序列化时,对象会通过之前序列化的数据完成实例化,不会调用构造函数。由于Java实例化时,其父类会被先实例化,因此遇到第一个没有实现Serializable的类,这时必须调用其无参构造函数完成对象实例化。

关于serialVersionUID 网络对象第一次上线使用时,需要设定serialVersionUID。serialVersionUID在《Java语言规范》有固定算法,跟类中各field的定义相关,如果没有显式赋值,JVM会默认算出一个进行网络传输。如果没有显式赋值,在你增减了field/修改了定义的情况下,serialVersionUID已被改变,这时新旧序列化后的字节流就不兼容了,反序列化时将会出现问题。没定义serialVersionUID,而又发生了serialVersionUID变化,网络两端只有所有机器都停掉,并且先后起有顺序时,才能不出丝毫差错。

static和transient修饰的字段不会被序列化。

序列化协议 Java语言规范中定义了默认的对象序列化协议–即将对象转换成字节流的协议。http://docs.Oracle.com/javase/1.5.0/docs/guide/serialization/spec/protocol.html 其实我们还可以使用其它的序列化协议,比如Google的Protobuf等。

Java中的序列化与反序列化

Java序列化机制的深入研究

Java对象序列化ObjectOutputStream和ObjectInputStream示例 

Java的序列化机制原理分析

Java对象序列化使用基础

利用序列化将Java对象深拷贝

相关内容

    暂无相关文章