Khai báo một biến final
hoặc không khai báo nó final
, nhưng giữ cho nó có hiệu quả cuối cùng có thể dẫn đến (phụ thuộc vào trình biên dịch) trong mã byte khác nhau.
Chúng ta hãy xem một ví dụ nhỏ:
public static void main(String[] args) {
final boolean i = true; // 6 // final by declaration
boolean j = true; // 7 // effectively final
if (i) { // 9
System.out.println(i);// 10
}
if (!i) { // 12
System.out.println(i);// 13
}
if (j) { // 15
System.out.println(j);// 16
}
if (!j) { // 18
System.out.println(j);// 19
}
}
Mã byte tương ứng của main
phương thức (Java 8u161 trên Windows 64 Bit):
public static void main(java.lang.String[]);
Code:
0: iconst_1
1: istore_1
2: iconst_1
3: istore_2
4: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
7: iconst_1
8: invokevirtual #22 // Method java/io/PrintStream.println:(Z)V
11: iload_2
12: ifeq 22
15: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
18: iload_2
19: invokevirtual #22 // Method java/io/PrintStream.println:(Z)V
22: iload_2
23: ifne 33
26: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
29: iload_2
30: invokevirtual #22 // Method java/io/PrintStream.println:(Z)V
33: return
Bảng số dòng tương ứng:
LineNumberTable:
line 6: 0
line 7: 2
line 10: 4
line 15: 11
line 16: 15
line 18: 22
line 19: 26
line 21: 33
Như chúng ta thấy mã nguồn tại dòng 12
, 13
, 14
không xuất hiện trong các mã byte. Đó là bởi vì i
là true
và sẽ không thay đổi trạng thái của nó. Do đó, mã này là không thể truy cập (nhiều hơn trong câu trả lời này ). Đối với cùng một lý do mã ở dòng 9
bỏ lỡ quá. Tình trạng i
không phải được đánh giá vì nó là true
chắc chắn.
Mặt khác mặc dù biến j
là một cách hiệu quả thức nó không được xử lý theo cách tương tự. Không có tối ưu hóa như vậy được áp dụng. Trạng thái của j
được đánh giá hai lần. Mã byte là như nhau bất kể j
là cuối cùng có hiệu quả .