JavaRush /Java Blog /Random-ID /Konstruktor Default dan Menjaga Integritas Kelas di Java
articles
Level 15

Konstruktor Default dan Menjaga Integritas Kelas di Java

Dipublikasikan di grup Random-ID
Saat mendesain kelas yang dimaksudkan untuk pewarisan (misalnya, kelas abstrak), dianggap sebagai praktik yang baik untuk tidak mengimplementasikan antarmuka Serializable, dan memutuskan secara individual di setiap kelas turunan apakah perlu diserialkan atau tidak. Namun, kelas tersebut harus memiliki konstruktor default agar mekanisme serialisasi dapat membuat objek dengan benar. Dan terkadang tidak ada cara untuk menyediakan konstruktor default tanpa merusak integritas kelas. Konstruktor default dan menjaga integritas kelas di Java - 1Kelas seperti itu sering kali harus mengambil beberapa objek sebagai parameter, yang tanpanya ia tidak dapat berfungsi secara normal, dan menyediakan konstruktor default akan melanggar integritas kelas. Dalam situasi seperti ini, Anda dapat menyediakan konstruktor, tetapi melarang bekerja dengannya hingga konstruktor tersebut diinisialisasi sepenuhnya. Untuk melakukan hal ini, Anda dapat memperkenalkan suatu keadaan ke dalam suatu kelas, dan mengizinkan metode-metodenya dipanggil hanya jika keadaan kelas ini “diinisialisasi”. Contoh dari buku "Java Efektif" :
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);
    }
}
Pada saat yang sama, semua metode kelas ini harus memeriksa status kelas saat ini dan mencegah penggunaan yang salah, dan metode readObject()serta harus didefinisikan dalam kelas turunan writeObject(). Tautan ke sumber asli: http://0agr.ru
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION