Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Final variables in class file format

Does class file format provide support for final keyword in case of using it with variables?
Or does it just deduce the effective finality of a variable from code and JIT compiler perform optimization based on it?

Here, in class file format documentation, they mentioned about final keyword, but only in case of using it with final block and final class.
There is nothing about final variables.

like image 689
Michał Szewczyk Avatar asked Oct 15 '16 08:10

Michał Szewczyk


2 Answers

No, there is no such information encoded in class file.

You may easily verify this by compiling a source file with a final local variable and without final - the result classes will be identical.

However, Java 8 added MethodParameters attribute that records information about names and access flags of method arguments. This means, you can check whether a method argument is final or not.

Just-in-time compilers do not need to know about final locals - they can easily determine the actual scope of any expression. Even if a variable is not final, e.g.

    int x = 1;
    // ... code A ...

    x = 2;
    // ... code B ...

the compilers will optimize the code A as if x is always 1, and the code B as if x is always 2.

like image 174
apangin Avatar answered Sep 21 '22 12:09

apangin


Maybe we should first reconsider the term “variable”. In most contexts, the term “variable” includes local variables, static and non-static fields and more than often even array elements (e.g., in the memory model). Since array elements do not support being final, the answer can only be given for fields and local variables.

For fields, there is the ACC_FINAL flag, which tells whether the field is final or not. It has different consequences. static final fields can only be written in the class initializer whereas final instance fields are not only writable in the constructor but also via Reflection with access override. A JVM trying to take a benefit from the final nature of an instance field when optimizing, has to take care to detect reflective modifications.

For local variables, there is no final flag, in fact, there is not even a formal declaration at all. In the Java byte code, local variables are only indices within the stack frame, reused at will without premonition. So a write to a local variable index could be either, a change of the variable or a reuse of the same index for a new variable, e.g. { int x=4; } { int y=5; } may get compiled to the same byte code as { int x=4; x=5; }.

For the JVM’s optimizer, it doesn’t matter anyway, as it will transform the operations on the local variables into SSA form, so, with the example above, the optimizer will treat the code as having to constants, c₁:=4 and c₂:=5, and depending on the position of the subsequent code it can be determined which constant is uses, in other words, it’s more than having “effectively final” variables, even changing variables can be treated like multiple final variables (in the absence of thread synchronization, even changes to heap variables may temporarily get a similar treatment).

like image 21
Holger Avatar answered Sep 18 '22 12:09

Holger