序列化与反序列化

基本概念

Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。

序列化的目的:实现对象远程传输、实现对象持久化保存


如何序列化

  • 只有实现了Serializable或者Externalizable接口的类的对象才能被序列化为字节序列。(不是则会抛出异常)
  • Serializable 是一个空接口,用来标识当前类可以被 ObjectOutputStream 序列化,以及被 ObjectInputStream 反序列化。
  • 序列化类的属性没有实现 Serializable 那么在序列化就会报错
  • 在反序列化过程中,它的父类如果没有实现序列化接口,那么将需要提供父类的无参构造函数来重新创建对象,否则会报错
  • 一个实现 Serializable 接口的子类也是可以被序列化的。
  • 静态成员变量是不能被序列化
  • transient 标识的对象成员变量不参与序列化

序列化代码示例:

1
2
3
4
5
BlackCat black = new BlackCat();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_PATH));
oos.writeObject(black);
oos.flush();
oos.close();

序列化ID

serialVersionUID主要影响反序列化,在进行反序列化时,JVM会把传进来的字节流中的serialVersionUID与本地实体类中的serialVersionUID进行比较,如果相同则认为是一致的,便可以进行反序列化,否则就会报序列化版本不一致的异常。

serialVersionUID 发生改变有三种情况:

  • 手动去修改导致当前的 serialVersionUID 与序列化前的不一样。
  • 没有指定时 JVM 内部会根据类结构去计算得到这个 serialVersionUID 值,在类结构发生改变时(属性增加,删除或者类型修改了)这种也是会导致 serialVersionUID 发生变化。
  • 假如类结构没有发生改变,并且没有定义 serialVersionUID ,但是反序列和序列化操作的虚拟机不一样也可能导致计算出来的 serialVersionUID 不一样。

注意事项:

  • serialVersionUID可以手动指定也可以借助工具生成
  • JVM 规范强烈建议我们手动声明一个版本号,最好是 private 和 final 的保证不变。

序列化步骤是什么

  • 将对象实例相关的类元数据输出
  • 递归地输出类的超类描述直到不再有超类
  • 类元数据完了以后,开始从最顶层的超类开始输出对象实例的实际数据值
  • 从上至下递归输出实例的数据

如何反序列化

代码示例:

1
2
3
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_PATH));
BlackCat black = (BlackCat) ois.readObject();
ois.close();

序列化单例

问题:程序中有一个单例的对象。如果对其进行序列化,再反序列化,则得到了另一个对象。破坏了其单例性。

解决方法是在类中定义readResolve方法:

1
2
3
4
5
6
7
8
public final class Singleton implements Serializable {
private Singleton() {}
private static final Singleton INSTANCE = new Singleton();
public static Singleton getInstance() { return INSTANCE; }
private Object readResolve() throws ObjectStreamException {
return INSTANCE;
}
}

这样,当反序列化时,就会调用这个readResolve方法返回我们制定好的对象。




版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接,感谢各位看官!!!

本文出自:monkeyGeek

座右铭:生于忧患,死于安乐

欢迎志同道合的朋友一起交流、探讨!

monkeyGeek
#

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×