JavaRush /Java 博客 /Random-ZH /Java 中的默认构造函数和保持类完整性
articles
第 15 级

Java 中的默认构造函数和保持类完整性

已在 Random-ZH 群组中发布
在设计用于继承的类(例如抽象类)时,最好不要实现接口Serializable,并在每个后代类中单独决定是否需要序列化。但是,这样的类必须具有默认构造函数,以便序列化机制正确创建对象。有时,无法在不破坏类完整性的情况下提供默认构造函数。 Java 中的默认构造函数和维护类完整性 - 1这样的类通常必须采用某个对象作为参数,否则它无法正常运行,并且提供默认构造函数将违反类的完整性。在这种情况下,您可以提供一个构造函数,但在它完全初始化之前禁止使用它。为此,您可以在类中引入一个状态,并允许仅当该类的状态为“初始化”时才调用其方法。《Effective java》一书中的示例:
public abstract class AbstractFoo {
    private int x, y;

    private enum State {
        NEW, INITIALIZING, INITIALIZED
    };

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

    protected AbstractFoo() {}

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

    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;
        init.set(State.INITIALIZED);
    }

    protected final int getX() {
        checkInit();
        return x;
    }

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

    private void checkInit() {
        if (init.get() != State.INITIALIZED) {
            throw new IllegalStateException("Uninitialized");
        }
    }
}

class Foo extends AbstractFoo implements Serializable {
    private void readObject(ObjectInputStream s) throws IOException,
            ClassNotFoundException {
        s.defaultReadObject();
        int x = s.readInt();
        int y = s.readInt();
        initialize(x, y);
    }

    private void writeObject(ObjectOutputStream s) throws IOException {
        s.defaultWriteObject();
        s.writeInt(getX());
        s.writeInt(getY());
    }

    public Foo(int x, int y) {
        super(x, y);
    }
}
同时,该类的所有方法都必须检查该类的当前状态并防止其错误使用,并且方法readObject()和必须在后代类中定义writeObject()。原始来源链接: http: //0agr.ru
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION