JavaRush /จาวาบล็อก /Random-TH /ตัวสร้างเริ่มต้นและการรักษาความสมบูรณ์ของคลาสใน Java
articles
ระดับ

ตัวสร้างเริ่มต้นและการรักษาความสมบูรณ์ของคลาสใน Java

เผยแพร่ในกลุ่ม
เมื่อออกแบบคลาสที่มีไว้สำหรับการสืบทอด (เช่น คลาสนามธรรม) ถือเป็นแนวปฏิบัติที่ดีที่จะไม่ใช้งานอินเทอร์เฟซSerializableและต้องตัดสินใจเป็นรายบุคคลในแต่ละคลาสสืบทอดว่าจำเป็นต้องทำให้เป็นอนุกรมหรือไม่ อย่างไรก็ตาม คลาสดังกล่าวต้องมีคอนสตรัคเตอร์เริ่มต้นเพื่อให้กลไกการทำให้ซีเรียลไลซ์สร้างอ็อบเจ็กต์ได้อย่างถูกต้อง และบางครั้งก็ไม่มีวิธีใดที่จะจัดเตรียมคอนสตรัคเตอร์เริ่มต้นโดยไม่ทำลายความสมบูรณ์ของคลาส ตัวสร้างเริ่มต้นและการรักษาความสมบูรณ์ของคลาสใน Java - 1คลาสดังกล่าวมักจะต้องใช้เป็นพารามิเตอร์ของอ็อบเจ็กต์บางตัวโดยที่ไม่สามารถทำงานได้ตามปกติ และการจัดเตรียมคอนสตรัคเตอร์เริ่มต้นจะละเมิดความสมบูรณ์ของคลาส ในสถานการณ์เช่นนี้ คุณสามารถจัดเตรียมตัวสร้างได้ แต่ห้ามไม่ให้ใช้งานตัวสร้างนั้นจนกว่าจะเริ่มต้นใช้งานโดยสมบูรณ์ ในการดำเนินการนี้ คุณสามารถแนะนำสถานะลงในคลาสได้ และอนุญาตให้เรียกใช้เมธอดได้ก็ต่อเมื่อสถานะของคลาสนี้ "เริ่มต้น" เท่านั้น ตัวอย่างจากหนังสือ"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);
    }
}
ในเวลาเดียวกัน วิธีการทั้งหมดของคลาสนี้จะต้องตรวจสอบสถานะปัจจุบันของคลาสและ ป้องกัน การใช้งานที่ไม่ถูกต้อง และวิธีการreadObject()และ จะต้องกำหนดไว้ในคลาสลูกหลาน writeObject()ลิงก์ไปยังแหล่งที่มาดั้งเดิม: http://0agr.ru
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION