Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Lệnh unreachable (vô hiệu) do biến final trong Java

Khi biến được khai báo final, giá trị của nó được xác định tại compile-time (constant variable) hoặc không thể gán lại. Compiler sử dụng constant folding để đánh giá điều kiện vòng lặp, dẫn đến phát hiện unreachable statement chính xác hơn.

Ví dụ: final variable gây unreachable

class DemoExample {
    final int a = 56, b = 99; // COMPILE-TIME CONSTANTS
    
    void funcSample() {
        while (a < b) {           // 56 < 99 → luôn true (constant expression)
            System.out.println("The first value is less than the second.");
        }
        System.out.println("This is an unreachable statement"); // COMPILE ERROR
    }
}

public class Demo {
    public static void main(String[] args) {
        DemoExample instance = new DemoExample();
        instance.funcSample();
    }
}

Kết quả Compile

Demo.java:11: error: unreachable statement
            System.out.println("This is an unreachable statement");
            ^
1 error

Tại sao final khác non-final?

Đặc điểmfinal (constant variable)non-final
Giá trị biết tạiCompile-time (constant folding)Runtime (flow analysis trong method)
Điều kiện loopĐánh giá constant expressionPhân tích data flow (definite assignment)
Unreachable detectionChắc chắn 100%Dựa trên phân tích cục bộ (có thể conservative)
Yêu cầu JLSConstant variable: final, primitive/String, init bằng constant expressionKhông

Constant Variable (JLS 4.12.4)

Biến được coi là constant variable nếu:

  • final
  • Kiểu primitive hoặc String
  • Khởi tạo ngay tại khai báo với constant expression (literal, operator trên constant, final constant variable khác).
final int A = 10;                    // Constant variable
final int B = A + 5;                 // Constant variable
final String S = "Hello";            // Constant variable
final Object O = new Object();       // KHÔNG (không phải primitive/String)
final int C; C = 10;                 // KHÔNG (không init tại khai báo)
final int D = System.currentTimeMillis(); // KHÔNG (không phải constant expression)

Ví dụ final KHÔNG gây unreachable (không phải constant variable)

class Test {
    final int x; // Blank final
    Test(int v) { x = v; }
    
    void method() {
        while (x > 0) { // x không phải constant variable (không init tại khai báo)
            System.out.println("Loop");
            // Compiler KHÔNG báo unreachable cho code sau loop
            // Vì không biết giá trị x tại compile-time
        }
        System.out.println("After loop"); // OK - không unreachable
    }
}

Các trường hợp unreachable liên quan final

// 1. if (false) với constant condition
final boolean DEBUG = false;
if (DEBUG) { System.out.println("Debug"); } // Block unreachable → compiler có thể optimize away, không báo lỗi (khác while)

// 2. Switch exhaustive (Java 14+)
final int x = 1;
switch (x) {
    case 1: System.out.println("One"); break;
    // default unreachable? Không báo lỗi, nhưng warning có thể.
}

// 3. Try-with-resources luôn close
try (AutoCloseable r = () -> {}) {
    return; // Code sau try block unreachable? Không, finally (close) vẫn chạy.
} 
System.out.println("After try"); // Reachable vì try block complete normally nếu không return/throw

Best Practice

  • Dùng final cho hằng số thực sự (config, magic numbers) – giúp compiler optimize và detect unreachable.
  • Tránh logic phức tạp trong condition của while/for nếu muốn compiler detect unreachable.
  • Dùng assert false hoặc throw new AssertionError() để mark unreachable code cố ý (ví dụ: switch exhaustive default case).
  • IDE (IntelliJ, Eclipse) highlight unreachable code real-time – sửa ngay khi thấy warning/error.