JAVA:在编译时加载静态值有什么好处?

问题描述

我这样写java代码:

final int value=0;

当我使用“Svace Static Analyzer”分析代码时,它显示: 此类包含一个实例 final 字段,该字段被初始化为编译时静态值,请考虑使该字段为静态---->

static final int value=0;

我知道静态值是在编译时加载的。谁能解释一下编译加载的优势?

解决方法

像下面这样的初始化将对于所有实例保持不变,因此它使您的代码更高效地声明它 static 以便它只会为类初始化一次,而不是为单个实例初始化.

final int value = 0;

另一方面,如果您通过构造函数参数初始化 value,例如

public class MyClass {
    final int value;

    public MyClass(int value) {
        this.value = value;
    }

    // ...
}

,各个实例可能具有不同的 value 值,因此分析器不会要求您将其声明为 static

此外,如果您有一个可变的 final 实例变量,例如

final List<Integer> value = new ArrayList<>();

,分析器不会要求您将其声明为 static,因为个别实例可能已用不同的整数列表填充 value

,

Scenario 1:

class Mango{
 final int marker = 10;
}
  1. 在类中,当您将变量声明为 final 并在声明期间对其进行初始化时,这意味着您不想从任何地方修改它。

  2. 在这种情况下,该类的所有创建对象都为该变量保持了相似的值。

  3. 另一方面,每当我们将变量声明为静态变量时,都会在类级别创建一个与对象共享的变量。该静态变量中的任何更改都会反映到其他对象操作中。

  4. 但实际上,在第 1 点和第 2 点,我们希望隐式实现第 3 点的行为。

因此,java 强制或建议您仅通过声明 marker 来创建 static 变量的一个副本。

class Mango{
 final static int marker = 10;
}

内存效率高、更干净且无歧义。

Scenario 2:

public class Mango {
    final int marker;
    
    Mango(int m){
        marker = m;
    }
}

这种类型的声明完全不同。在这种情况下,Mango 类的每个实例都有自己的 marker 变量,并且只能初始化一次。

第一种类型的声明确保类级别的最终行为,第二种类型的声明确保对象级别的最终行为。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...