一、序列化算法的步骤

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

二、JDK序列化为啥必须要实现Serializable 接口

三、序列化和单例模式

所谓单例:就是单例模式就是在整个全局中(无论是单线程还是多线程),该对象只存在一个实例,而且只应该存在一个实例,没有副本。
序列化对单例有破坏
1、通过对某个对象的序列化与反序列化得到的对象是一个新的对象,这就破坏了单例模式的单例性。
2、我们知道readObject()的时候,底层运用了反射的技术。
序列化会通过反射调用无参数的构造方法创建一个新的对象。
这破坏了对象的单例性。

举例说明:
实现序列化的单例

  1. public class Singleton implements Serializable {
  2. // volatile 禁止指令重排序
  3. private static volatile Singleton instance;
  4. /**
  5. * 私有化构造器,这样该类就不会被实例化;
  6. */
  7. private Singleton() {
  8. }
  9. public static Singleton getInstance() {
  10. if (instance == null) {
  11. synchronized (Singleton.class) {
  12. if (instance == null) {
  13. instance = new Singleton();
  14. return instance;
  15. }
  16. }
  17. }
  18. return instance;
  19. }
  20. /**
  21. * 提供readResolve()方法
  22. * 当JVM反序列化恢复一个新对象时,系统会自动调用readResolve()方法返回指定好的对象
  23. * 从而保证系统通过反序列化机制不会产生多的Java对象
  24. *
  25. * @return 单例对象
  26. * @throws ObjectStreamException 异常
  27. */
  28. private Object readResolve() throws ObjectStreamException {
  29. return instance;
  30. }
  31. }

测试类:

  1. @Test
  2. public void testSingeton() throws Exception {
  3. //获取instance 对象
  4. Singleton instance = Singleton.getInstance();
  5. // 获取文件输出流
  6. FileOutputStream fileOutputStream = new FileOutputStream("d:\\Test.txt");
  7. // 获取对象输出流
  8. ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
  9. // 输出对象
  10. objectOutputStream.writeObject(instance);
  11. // 关闭资源
  12. objectOutputStream.close();
  13. fileOutputStream.close();
  14. // 获取对象输入流
  15. ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("d:\\Test.txt"));
  16. // 读取对象
  17. Object object = objectInputStream.readObject();
  18. // 判断两个对象是否相等,返回true/false
  19. System.out.println(instance == object);
  20. }

当前结果: false ;
原因:因为JVM在反序列化的时候会通过反射创建了一个新的对象;

如何避免 呢 ?
在单例类中提供一个readSolve()方法,当JVM反序列化恢复一个新对象时,系统会自动调用readResolve()方法返回指定好的对象。从而保证系统通过反序列化机制不会产生多的Java对象。
https://blog.csdn.net/m0_48837505/article/details/110084930

引用

https://blog.csdn.net/weixin_39723544/article/details/80527550
https://blog.csdn.net/fuhao_ma/article/details/102969349
https://blog.csdn.net/weixin_39800144/article/details/103432511