JavaRush /Blog Java /Random-ES /Constructor predeterminado y preservación de la integrida...
articles
Nivel 15

Constructor predeterminado y preservación de la integridad de la clase en Java

Publicado en el grupo Random-ES
Al diseñar clases destinadas a la herencia (por ejemplo, clases abstractas), se considera una buena práctica no implementar una interfaz Serializabley decidir individualmente en cada clase descendiente si es necesario serializarla o no. Sin embargo, dicha clase debe tener un constructor predeterminado para que los mecanismos de serialización creen correctamente el objeto. Y a veces no hay forma de proporcionar un constructor predeterminado sin romper la integridad de la clase. Constructor predeterminado y mantenimiento de la integridad de la clase en Java - 1Una clase así a menudo debe tomar como parámetro algún objeto sin el cual no puede funcionar normalmente, y proporcionar un constructor predeterminado violará la integridad de la clase. En tal situación, puede proporcionar un constructor, pero prohibir trabajar con él hasta que esté completamente inicializado. Para hacer esto, puede introducir un estado en una clase y permitir que se llamen sus métodos solo si el estado de esta clase está "inicializado". Ejemplo del libro "Java efectivo" :

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);
    }
}
Al mismo tiempo, todos los métodos de esta clase deben verificar el estado actual de la clase y evitar su uso incorrecto, y los métodos readObject()y deben definirse en la clase descendiente writeObject(). Enlace a la fuente original: http://0agr.ru
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION