Khai báo một biến finalhoặ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 mainphươ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, 14không xuất hiện trong các mã byte. Đó là bởi vì ilà truevà 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 9bỏ lỡ quá. Tình trạng ikhông phải được đánh giá vì nó là truechắc chắn.
Mặt khác mặc dù biến jlà 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ể jlà cuối cùng có hiệu quả .