JavaRush /Java Blog /Random EN /Default Constructor and Preserving Class Integrity in Jav...
articles
Level 15

Default Constructor and Preserving Class Integrity in Java

Published in the Random EN group
When designing classes intended for inheritance (for example, abstract classes), it is considered good practice not to implement an interface Serializable, and to decide individually in each descendant class whether it needs to be serialized or not. However, such a class must have a default constructor in order for the serialization mechanisms to correctly create the object. And sometimes there is no way to provide a default constructor without breaking the integrity of the class. Default constructor and maintaining class integrity in Java - 1Such a class often must take as a parameter some object without which it cannot function normally, and providing a default constructor will violate the integrity of the class. In such a situation, you can provide a constructor, but prohibit working with it until it is fully initialized. To do this, you can introduce a state into a class, and allow its methods to be called only if the state of this class is “initialized”. Example from the book "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);
    }
}
At the same time, all methods of this class must check the current state of the class and prevent its incorrect use, and the methods readObject()and must be defined in the descendant class writeObject(). Link to the original source: http://0agr.ru
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION