Analyzing the bytecode of this simple class, I have come to the conclusion that the compiler doesn't retain any information about a local variable being final
. This seems weird though, since I believe the HotSpot compiler could actually use this information to do optimizations.
Code:
public static void main(String[] args)
{
final int i = 10;
System.out.println(i);
}
Bytecode:
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: bipush 10
2: istore_1
3: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
6: bipush 10
8: invokevirtual #22 // Method java/io/PrintStream.println:(I)V
11: return
LineNumberTable:
line 7: 0
line 8: 3
line 9: 11
LocalVariableTable:
Start Length Slot Name Signature
0 12 0 args [Ljava/lang/String;
3 9 1 i I
Is there any specific reason not to retain the access flags of a local variable, other than saving disk space? Because to me, it seems that being final
is a relatively non-trivial property of a variable.
The
final
modifier is not present in the bytecode but the compiler already uses this information to make some optimization. Although your example doesn't show it, the compiler may inline thefinal
variable's value in the bytecode representation of the method, leading to a better performance. Something like the below can show the difference:The generated bytecode are respectively for each method: