Wenn Sie eine Variable finaldeklarieren oder nicht deklarieren, sie finaljedoch endgültig halten, kann dies (abhängig vom Compiler) zu einem anderen Bytecode führen.
Schauen wir uns ein kleines Beispiel an:
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
}
}
Der entsprechende Bytecode der mainMethode (Java 8u161 unter 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
Die entsprechende Zeilennummertabelle:
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
Da wir den Quellcode an den Linien zu sehen 12, 13, 14erscheint nicht in dem Byte - Code. Das iliegt truedaran, dass es seinen Zustand ändert und nicht ändern wird. Daher ist dieser Code nicht erreichbar (mehr in dieser Antwort ). Aus dem gleichen Grund 9fehlt auch der Code in der Zeile . Der Zustand von imuss nicht ausgewertet werden, da dies truesicher ist.
Auf der anderen Seite ist die Variable jzwar endgültig, wird aber nicht auf die gleiche Weise verarbeitet. Es werden keine derartigen Optimierungen angewendet. Der Zustand von jwird zweimal ausgewertet. Der Bytecode ist derselbe, unabhängig davon j, ob er tatsächlich endgültig ist .