我最近遇到了一个声明了以下字段的类:
private final int period = 1000;
在这种特殊情况下,作者原本打算使它也是静态的,因为价值在任何时候都无法改变,没有真正的功能理由不将它声明为静态,但它让我想知道Java如何处理final和final静态原语。
特别是:
1)最终的静态图元是如何存储的?它们是否只是直接编译成使用它们的表达式?
2)如果它们实际上是分配存储,那么包含类的每个实例是否必须维护对该位置的引用? (在这种情况下,对于少于4个字节的基元,该类的每个实例实际上都会大于它只是直接包含基元,就像它在非静态情况下那样)
3)编译器现在是否足够聪明,以确定在上述情况下,变量是“有效静态”的,因为不可能让不同的实例包含不同的值,因此优化它与最终的静态值相似?
答案 0 :(得分:5)
1)最终的静态图元是如何存储的?它们是否只是直接编译成使用它们的表达式?
不直接编译到表达式中。它们被编译到.class文件中,并由操作码ldc
引用。
2)如果它们实际上是分配存储,那么包含类的每个实例是否必须维护对该位置的引用? (在这种情况下,对于少于4个字节的基元,该类的每个实例实际上都会大于它只是直接包含基元,就像它在非静态情况下那样)
不,“引用”被烘焙到字节码中,因此不需要在每个实例的基础上存储任何内容。
3)编译器现在是否足够聪明,以确定在上述情况下,变量是“有效静态”的,因为不可能让不同的实例包含不同的值,因此优化它与最终的静态值相似?
不确定,但我怀疑它是否在编译器级别进行了优化。 JIT可能会发挥作用。但是,我不确定你期待什么样的“性能差异”。无论如何,性能影响都可以忽略不计。 (静态/非静止/最终/非最终)