Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

วิธีสร้างตัวแปรที่ตั้งค่าได้ครั้งเดียวแต่ไม่ใช่ final ใน Java

ตัวแปร final เมื่อกำหนดค่าแล้วจะแก้ไขไม่ได้ หากพยายามกำหนดค่าครั้งที่สองจะเกิด compile-time error

ตัวอย่าง final variable

public class FinalExample {
    final int j = 100;
    public static void main(String[] args){
        FinalExample obj = new FinalExample();
        obj.j = 500; // Compile error: cannot assign a value to final variable j
        System.out.println(obj.j);
    }
}

บรรลุฟังก์ชันคล้าย final โดยไม่ใช้คีย์เวิร์ด final

ทำให้ตัวแปรเป็น private และตั้งค่าผ่าน setter method ที่ตรวจสอบว่าถูกเรียกครั้งแรกหรือไม่ หากเรียกครั้งที่สอง ให้คงค่าเดิมหรือโยน Exception

ตัวอย่างการทำงาน

public class FinalExample {
    private Integer num;
    public void setNum(int num){
        this.num = this.num == null ? num : this.num; // ตั้งค่าครั้งแรกเท่านั้น
    }
    
    private String data;
    public void setData(String data) {
        this.data = this.data == null ? data : demo();
    }
    
    public String demo() {
        String msg = "You cannot set value to the variable data for the second time";
        throw new RuntimeException(msg);
    }
    
    public static void main(String[] args){
        FinalExample obj = new FinalExample();
        obj.setNum(200);
        System.out.println(obj.num); // 200
        obj.setNum(500);
        System.out.println(obj.num); // 200 (ค่าเดิม)
        obj.setData("hello");
        obj.setData("sample data"); // โยน RuntimeException
    }
}

ผลลัพธ์

200
200
Exception in thread "main" java.lang.RuntimeException: You cannot set value to the variable data for the second time

รูปแบบอื่น: ใช้ Flag boolean

public class OnceSettable {
    private String value;
    private boolean initialized = false;
    
    public void setValue(String value) {
        if (initialized) {
            throw new IllegalStateException("Value already set");
        }
        this.value = value;
        initialized = true;
    }
    
    public String getValue() {
        return value;
    }
}

สรุป

เทคนิคนี้เหมาะสำหรับกรณีที่ต้องการควบคุมการตั้งค่าผ่าน logic เพิ่มเติม (เช่น validation, logging, lazy initialization) ซึ่ง final ทำไม่ได้