JavaRush /Java-Blog /Random-DE /Standardkonstruktor und Wahrung der Klassenintegrität in ...
articles
Level 15

Standardkonstruktor und Wahrung der Klassenintegrität in Java

Veröffentlicht in der Gruppe Random-DE
Beim Entwerfen von Klassen, die zur Vererbung vorgesehen sind (z. B. abstrakte Klassen), gilt es als bewährte Vorgehensweise, keine Schnittstelle zu implementieren Serializableund in jeder Nachkommenklasse einzeln zu entscheiden, ob sie serialisiert werden muss oder nicht. Allerdings muss eine solche Klasse über einen Standardkonstruktor verfügen, damit die Serialisierungsmechanismen das Objekt korrekt erstellen können. Und manchmal gibt es keine Möglichkeit, einen Standardkonstruktor bereitzustellen, ohne die Integrität der Klasse zu beeinträchtigen. Standardkonstruktor und Aufrechterhaltung der Klassenintegrität in Java - 1Eine solche Klasse muss häufig ein Objekt als Parameter verwenden, ohne das sie nicht normal funktionieren kann, und die Bereitstellung eines Standardkonstruktors verletzt die Integrität der Klasse. In einer solchen Situation können Sie einen Konstruktor bereitstellen, aber die Arbeit damit verbieten, bis er vollständig initialisiert ist. Dazu können Sie einen Zustand in eine Klasse einführen und den Aufruf ihrer Methoden nur dann zulassen, wenn der Zustand dieser Klasse „initialisiert“ ist. Beispiel aus dem Buch „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);
    }
}
Gleichzeitig müssen alle Methoden dieser Klasse den aktuellen Status der Klasse überprüfen und deren falsche Verwendung verhindern, und die Methoden readObject()und müssen in der Nachfolgeklasse definiert sein writeObject(). Link zur Originalquelle: http://0agr.ru
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION