[英]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? 或者它只是从代码中推断出变量的有效终结性而JIT编译器基于它执行优化?
Here , in class file format documentation, they mentioned about final keyword, but only in case of using it with final block and final class . 这里 ,在类文件格式文档中,他们提到了关于final关键字,但仅限于将其与final块和final类一起使用的情况。
There is nothing about final variables . 最终变量没有任何内容。
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. 您可以通过使用final
局部变量编译源文件并且没有final
来轻松验证这一点 - 结果类将是相同的。
However, Java 8 added MethodParameters
attribute that records information about names and access flags of method arguments. 但是,Java 8添加了MethodParameters
属性,该属性记录有关方法参数的名称和访问标志的信息。 This means, you can check whether a method argument is final
or not. 这意味着,您可以检查方法参数是否为final
。
Just-in-time compilers do not need to know about final
locals - they can easily determine the actual scope of any expression. 即时编译器不需要了解final
本地化 - 他们可以轻松确定任何表达式的实际范围。 Even if a variable is not final, eg 即使变量不是最终的,例如
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
. 编译器将优化代码A
,就像x
始终为1
,代码B
就像x
始终为2
。
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 (eg, in the memory model). 在大多数情况下,术语“变量”包括局部变量, static
和非static
字段以及甚至通常甚至是数组元素(例如,在存储器模型中)。 Since array elements do not support being final
, the answer can only be given for fields and local variables. 由于数组元素不支持final
,因此只能为字段和局部变量给出答案。
For fields, there is the ACC_FINAL
flag, which tells whether the field is final
or not. 对于场, 有 ACC_FINAL
标志,它告诉字段是否是final
与否。 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. static final
字段只能在类初始值设定项中写入,而final
实例字段不仅可以在构造函数中写入,还可以通过具有访问覆盖的反射来写入。 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. 试图在优化时从实例字段的final
性质中获益的JVM必须注意检测反射修改。
For local variables, there is no final
flag, in fact, there is not even a formal declaration at all. 对于局部变量,没有final
标志,事实上,根本没有正式的声明。 In the Java byte code, local variables are only indices within the stack frame , reused at will without premonition. 在Java字节代码中,局部变量只是堆栈帧中的索引,可以随意重用而不会预感。 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, eg { int x=4; } { int y=5; }
因此,对局部变量索引的写入可以是变量的变化,也可以是新变量的相同索引的重用,例如{ int x=4; } { int y=5; }
{ int x=4; } { int y=5; }
{ int x=4; } { int y=5; }
may get compiled to the same byte code as { int x=4; x=5; }
{ int x=4; } { int y=5; }
可以编译为与{ int x=4; x=5; }
相同的字节代码 { int x=4; x=5; }
{ int x=4; x=5; }
. { 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). 对于JVM的优化器,无论如何都没关系,因为它会将局部变量的操作转换为SSA形式 ,因此,在上面的例子中,优化器会将代码视为必须为常量, c₁:=4
和c₂:=5
,并且根据后续代码的位置,可以确定使用哪个常量,换句话说,它不仅仅具有“有效最终”变量,甚至可以将变量变量视为多个final
变量(在没有变量的情况下)线程同步,甚至更改堆变量可能会暂时得到类似的处理)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.