java序列化--java.io.Serializable接口解析
使用java以来 序列化随处可见 至于为什么要用序列化 序列化能解决什么问题 作为一个普通的码农 一般不怎么会去深入研究 由于最近在看mina和公司内部涉及到nio框架的一些源码 里面涉及到hession java这两种序列化 至于hession序列化为什么会诞生以及在apache项目中使用如此广泛 以及java本身序列化存在哪些缺陷 甚是不解 为了解答上面抛出来的疑惑 以及进一步了解java的序列化机制 这里开个小头 从java的序列化接口Serializable开始说起
jdk包里的Serializable接口的注释主要说明了以下几点
类通过实现Serializable接口来启用序列化 否则该类的任何状态将无法被序列化 同时也无法用于反序列化
若继承的父类没有实现Serializable接口 但是又想让子类可序列化 有三个注意事项
a) 子类实现Serializable接口
b) 子类必须有可访问的无参构造方法 用于保存和恢复父类的public或protected或同包下的package字段的状态 否则在序列化或反序列化时会抛出RuntimeException异常
c) 对于序列化后的子类 在进行反序列化时 理论上无法初始化父类中private(不可访问)对象变量的状态或值
在对可序列化类中的属性进行序列化时 如果遇到不可序列化的对象变量 此时会针对不可序列化的类抛出NotSerializableException异常
对于可序列化的非数组类 强烈建议显示声明static型 long型 final型serialVersionUID字段用于标识当前序列化类的版本号 否则在跨操作系统 跨编译器之间进行序列化和反序列化时容易出现InvalidClassException异常
对于可序列化类中的static transient对象变量 在序列化时无法保存其状态或值 static对象变量在反序列化时取得的值为当前jvm中对应类中对应static变量的值 而transient(瞬态)关键字则一般用于标识那些在序列化时不需要传递的状态变量
简单的测试代码
import java io FileInputStream import java io FileNotFoundException import java io FileOutputStream import java io IOException import java io ObjectInputStream import java io ObjectOutputStream import java io Serializable
/** * 序列化测试 * * @author sume * */ public class SerializableImpl implements Serializable {
private static final long serialVersionUID = L
static String staticVal = static transient String transientVal = transient String val = val
/** * main */ public static void main(String[] args) throws FileNotFoundException IOException ClassNotFoundException { // 序列化 SerializableImpl sila = new SerializableImpl() ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream( Serializable txt )) objectOutputStream writeObject(sila ) objectOutputStream close()
// 反序列化 SerializableImpl staticVal = static ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream( Serializable txt )) SerializableImpl sila = (SerializableImpl) objectInputStream readObject() objectInputStream close()
// 比较各个属性的值 System out println(sila staticVal) System out println(sila transientVal) System out println(sila val) } }输出结果 static null val 从输出结果可以看出
反序列化后类中static型变量staticVal的值为当前jvm中对应static变量的值 为 static 而不是序列化时的值 static
transient关键字标识的变量的状态并没有在序列化中被保存 因此反序列化后
transientVal变量的值为null
第三个为常见的对象状态在序列化和反序列化过程中的传递
lishixinzhi/Article/program/Java/hx/201311/26282