JavaRush /Blog Java /Random-VI /Trình xây dựng mặc định và bảo toàn tính toàn vẹn của lớp...
articles
Mức độ

Trình xây dựng mặc định và bảo toàn tính toàn vẹn của lớp trong Java

Xuất bản trong nhóm
Khi thiết kế các lớp dành cho kế thừa (ví dụ: các lớp trừu tượng), việc không triển khai giao diện được coi là một cách thực hành tốt Serializablevà quyết định riêng lẻ trong mỗi lớp con cháu xem nó có cần được tuần tự hóa hay không. Tuy nhiên, một lớp như vậy phải có một hàm tạo mặc định để các cơ chế tuần tự hóa tạo đối tượng một cách chính xác. Và đôi khi không có cách nào để cung cấp hàm tạo mặc định mà không phá vỡ tính toàn vẹn của lớp. Hàm tạo mặc định và duy trì tính toàn vẹn của lớp trong Java - 1Một lớp như vậy thường phải lấy một tham số nào đó đối tượng mà không có nó thì nó không thể hoạt động bình thường và việc cung cấp một hàm tạo mặc định sẽ vi phạm tính toàn vẹn của lớp. Trong tình huống như vậy, bạn có thể cung cấp một hàm tạo nhưng cấm làm việc với nó cho đến khi nó được khởi tạo hoàn toàn. Để làm điều này, bạn có thể đưa một trạng thái vào một lớp và chỉ cho phép các phương thức của nó được gọi nếu trạng thái của lớp này được “khởi tạo”. Ví dụ từ cuốn sách "Java hiệu quả" :
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);
    }
}
Đồng thời, tất cả các phương thức của lớp này phải kiểm tra trạng thái hiện tại của lớp và ngăn chặn việc sử dụng nó không đúng, cũng như các phương thức readObject()và phải được định nghĩa trong lớp con writeObject(). Link nguồn gốc: http://0agr.ru
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION