JavaRush /Blog Java /Random-MS /Pembina Lalai dan Memelihara Integriti Kelas di Jawa
articles
Tahap

Pembina Lalai dan Memelihara Integriti Kelas di Jawa

Diterbitkan dalam kumpulan
Apabila mereka bentuk kelas yang bertujuan untuk warisan (contohnya, kelas abstrak), adalah dianggap sebagai amalan yang baik untuk tidak melaksanakan antara muka Serializabledan memutuskan secara individu dalam setiap kelas keturunan sama ada ia perlu disiri atau tidak. Walau bagaimanapun, kelas sedemikian mesti mempunyai pembina lalai agar mekanisme penyiaran dapat mencipta objek dengan betul. Dan kadangkala tiada cara untuk menyediakan pembina lalai tanpa memecahkan integriti kelas. Pembina lalai dan mengekalkan integriti kelas dalam Java - 1Kelas sedemikian selalunya mesti mengambil sebagai parameter beberapa objek yang tanpanya ia tidak dapat berfungsi secara normal, dan menyediakan pembina lalai akan melanggar integriti kelas. Dalam keadaan sedemikian, anda boleh menyediakan pembina, tetapi melarang bekerja dengannya sehingga ia dimulakan sepenuhnya. Untuk melakukan ini, anda boleh memperkenalkan keadaan ke dalam kelas, dan membenarkan kaedahnya dipanggil hanya jika keadaan kelas ini "dimulakan". Contoh dari buku "Jawa berkesan" :
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 masa yang sama, semua kaedah kelas ini mesti menyemak keadaan semasa kelas dan mengelakkan penggunaannya yang salah, dan kaedah readObject()dan mesti ditakrifkan dalam kelas keturunan writeObject(). Pautan ke sumber asal: http://0agr.ru
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION