Wenn Sie eine Variable final
deklarieren oder nicht deklarieren, sie final
jedoch 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 main
Methode (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
, 14
erscheint nicht in dem Byte - Code. Das i
liegt true
daran, dass es seinen Zustand ändert und nicht ändern wird. Daher ist dieser Code nicht erreichbar (mehr in dieser Antwort ). Aus dem gleichen Grund 9
fehlt auch der Code in der Zeile . Der Zustand von i
muss nicht ausgewertet werden, da dies true
sicher ist.
Auf der anderen Seite ist die Variable j
zwar endgültig, wird aber nicht auf die gleiche Weise verarbeitet. Es werden keine derartigen Optimierungen angewendet. Der Zustand von j
wird zweimal ausgewertet. Der Bytecode ist derselbe, unabhängig davon j
, ob er tatsächlich endgültig ist .