简体   繁体   English

类文件格式的最终​​变量

[英]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₁:=4c₂:=5 ,并且根据后续代码的位置,可以确定使用哪个常量,换句话说,它不仅仅具有“有效最终”变量,甚至可以将变量变量视为多个final变量(在没有变量的情况下)线程同步,甚至更改堆变量可能会暂时得到类似的处理)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM