Changed the "final" modifier lost in Bytecode?

Analyzing the bytecode of this simple class, I came to the conclusion that the compiler does not save information about the local variable final . This seems strange, though, since I believe that the HotSpot compiler can really use this information for optimization.

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 save the access flags of a local variable other than saving disk space? Because it seems to me that final is a relatively non-trivial property of a variable.

+6
source share
1 answer

The final modifier is missing in the bytecode, but the compiler already uses this information for some optimization. Although your example does not show it, the compiler can embed the value of the final variable in the representation of the byte code of the method, which will lead to better performance. Something like below might show the difference:

 public int addFinal() { final int i = 10; final int j = 10; return i + j; } public int addNonFinal() { int i = 10; int j = 10; return i + j; } 

The generated bytecode, respectively, for each method:

 // addFinal bipush 10 istore_1 bipush 10 istore_2 bipush 20 ireturn // addNonFinal bipush 10 istore_1 bipush 10 istore_2 iload_1 iload_2 iadd ireturn 
+7
source

Source: https://habr.com/ru/post/986920/


All Articles