为什么 Java 不允许在构造函数中初始化 static final 变量(例如 static final int d)?

Why Java wouldn't allow initialisation of static final variable (e.g. static final int d) in constructor?

我在 Java 中尝试初始化不同类型的变量。我可以在构造函数中初始化最终变量(例如 final int b)和静态变量(例如 static int c),但我不能在构造函数中初始化静态最终变量(例如 static final int d)。 IDE 也显示错误信息。

为什么 Java 不允许在构造函数中初始化静态最终变量?

public class InitialisingFields {
    int a;
    final int b;
    static int c;
    static final int d;

    InitialisingFields(){
        a = 1;
        b = 2;
        c = 3;
        d = 4;
    }

    public static void main(String[] args) {
        InitialisingFields i = new InitialisingFields(); 
    }

}

错误信息:

Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - cannot assign a value to final variable d
    at JTO.InitialisingFields.<init>(InitialisingFields.java:22)
    at JTO.InitialisingFields.main(InitialisingFields.java:26)
Java Result: 1

您不能重新分配 final 字段。 final 意味着变量不能改变。删除 final 就可以了。

class的所有实例共享一个静态变量,因此每次创建class的实例时,都会再次分配同一个变量。由于是final,所以只能赋值一次。所以不允许。

static final 变量应该保证只赋值一次。因此,它们既可以在声明它们的同一表达式中赋值,也可以在只执行一次的静态初始化程序块中赋值。

因为

  1. 无论是否创建 class 的实例,都必须设置静态变量,因此它必须发生在构造函数之外;
  2. 它只能设置一次,因此您无法在第二次创建实例时更改它的值。

你可以在初始化之前读取一个static final变量,它的值将是该类型的默认值,例如

class Nasty {
  static final int foo = yuk();
  static final int bar = 1;

  static int yuk() {
    System.out.println(bar);  // prints 0.
    return 99;
  }
}

然而,这是一个奇怪的案例,几乎可以肯定不是我们想要的。