gpt4 book ai didi

java - 将无参数构造函数添加到不可序列化的可扩展类

转载 作者:行者123 更新时间:2023-12-02 00:34:50 27 4
gpt4 key购买 nike

将无参数构造函数添加到不可序列化、可扩展的类中有何特别之处。

在Effective java中,作者谈到了这个话题。

Naively adding a parameterless constructor and a separate initialization method to a class whose remaining constructors establish its invariants would complicate the state space, increasing the likelihood of error.

以下代码复制自Effective Java 第二版[第292-293页]

 public class AbstractFoo {
private int x, y; // Our state

// This enum and field are used to track initialization
private enum State {
NEW, INITIALIZING, INITIALIZED
};

private final AtomicReference<State> init = new AtomicReference<State>(
State.NEW);

public AbstractFoo(int x, int y) {
initialize(x, y);
}

// This constructor and the following method allow
// subclass's readObject method to initialize our state.
protected AbstractFoo() {
}

protected final void initialize(int x, int y) {
if (!init.compareAndSet(State.NEW, State.INITIALIZING))
throw new IllegalStateException("Already initialized");
this.x = x;
this.y = y;
// ... // Do anything else the original constructor did
init.set(State.INITIALIZED);
}

// These methods provide access to internal state so it can
// be manually serialized by subclass's writeObject method.
protected final int getX() {
checkInit();
return x;
}

protected final int getY() {
checkInit();
return y;
}

// Must call from all public and protected instance methods
private void checkInit() {
if (init.get() != State.INITIALIZED)
throw new IllegalStateException("Uninitialized");
}
// ... // Remainder omitted

}

All public and protected instance methods in AbstractFoo must invoke checkInit before doing anything else. This ensures that method invocations fail quickly and cleanly if a poorly written subclass fails to initialize an instance. Note that the initialized field is an atomic reference (java.util.concurrent. atomic.AtomicReference). This is necessary to ensure object integrity in the face of a determined adversary. In the absence of this precaution, if one thread were to invoke initialize on an instance while a second thread attempted to use it, the second thread might see the instance in an inconsistent state.

我们为什么要这样做?我并不完全理解这一点。谁能解释一下吗?

最佳答案

我在看这本书的时候也遇到了同样的问题。我在那个地方有点困惑。经过一些研究,我发现了这一点。

http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html

阅读本文。据那“在反序列化期间,将使用该类的公共(public)或 protected 无参数构造函数来初始化不可序列化类的字段。无参数构造函数必须可供可序列化的子类访问。可序列化子类的字段将被恢复来自流”

我想这回答了你的问题。希望这会有所帮助。如果本评论有什么错误的地方,欢迎指正。

关于java - 将无参数构造函数添加到不可序列化的可扩展类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8080605/

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