gpt4 book ai didi

java - Effective Java Item #77 - 单例对象的序列化 - 为什么我必须使用 readResolve?

转载 作者:行者123 更新时间:2023-11-29 08:15:40 26 4
gpt4 key购买 nike

Effective Java #77 声明我们必须使用 readResolve 来在序列化期间保留 Singleton 保证。他们用过这个例子。

public class Elvis implements Serializable{
public static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public void leaveTheBuilding() { ... }

他们建议使用

If the Elvis class is made to implement Serializable, the following readResolve method suffices to guarantee the singleton property:

// readResolve for instance control - you can do better!
private Object readResolve() {
// Return the one true Elvis and let the garbage collector
// take care of the Elvis impersonator.
return INSTANCE; }

This method ignores the deserialized object, returning the distinguished Elvis instance that was created when the class was initialized.

  • 现在的问题是序列化再次加载类有两个猫王实例?
  • 如果类只加载一次那么我们应该只有一个猫王的实例,因为静态字段未序列化并且是期间未恢复反序列化和
  • 另一个猫王从哪里来实例来了符合垃圾收集条件readResolve(防止逃避反序列化过程)。这能解释一下吗?

最佳答案

  • 该类仅加载一次(除非您对类加载器进行了处理,但类实际上是不同的)。上述代码的反序列化确实创建了一个新的 Elvis。您需要使用串行代理来避免这种情况。

  • 虽然有两个 Elvis 实例,但 Elvis.INSTANCE 只指向一个。

  • 反序列化构造一个对象而不调用执行可序列化类的任何构造函数(但是它确实执行最派生的不可序列化基类的无参数构造函数)。

(顺便说一句,你还没有让你的类 final,所以即使是子类也可以被反序列化。顺便说一下,你提议的 readResolve 方法不会被调用对于子类,因为它是 private。)

关于java - Effective Java Item #77 - 单例对象的序列化 - 为什么我必须使用 readResolve?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5078785/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com