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ểm | final (constant variable) | non-final |
|---|---|---|
| Giá trị biết tại | Compile-time (constant folding) | Runtime (flow analysis trong method) |
| Điều kiện loop | Đánh giá constant expression | Phân tích data flow (definite assignment) |
| Unreachable detection | Chắc chắn 100% | Dựa trên phân tích cục bộ (có thể conservative) |
| Yêu cầu JLS | Constant variable: final, primitive/String, init bằng constant expression | Khô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
finalcho 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/fornếu muốn compiler detect unreachable. - Dùng
assert falsehoặcthrow 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.