【问题标题】:Initializing static final variables in java [duplicate]在java中初始化静态最终变量[重复]
【发布时间】:2018-03-06 20:29:51
【问题描述】:
public class Test {

    private static final int A;

    static {
        A = 5;
    }
}

这种初始化静态最终变量 A 的方式可以正常工作。

public class Test {
    private static final int A;

    static {
        Test.A = 5;
    }   
}

这种方式会产生编译错误“无法为最终变量'A'赋值。

为什么?

【问题讨论】:

  • 不确定,但可能是因为要执行 Test.A = 5,您需要一个 Test 实例。并且实例创建后不能赋值。
  • @AlperAkture:不,这不需要Test 的实例。
  • 这是静态的要点,不涉及实例。
  • 我不会那么介意。像这样的代码非常罕见,你真的不需要它。我确信这是一些技术问题,并且与 JLS 定义事物的确切方式有关,可能与何时执行 static 块以及何时可以使用 Test.A 进行引用有关。尽管如此,有趣的地方,我也很想知道详细的答案。

标签: java


【解决方案1】:

rules for Definite Assignment指定:

设C为类,V为空白static finalC的成员字段, 在 C 中声明。然后:

  • 在最左边的枚举常量静态初始化器之前,V 肯定是未分配的(而且也不是肯定分配的) (§8.7),或 C 的静态变量初始化器。

  • V 在 C 的枚举常量、静态初始化器或静态变量初始化器之前 [un] 赋值,除了最左边的当且仅当 V 是 [un] 在前面的枚举常量、静态初始化器或 C的静态变量初始化器。

通俗地说:

  • 使用静态初始化程序通过引用其简单名称来初始化static final 字段是可以的,因为该字段肯定是在初始化程序之后分配的。实际上,在声明静态初始化程序的类中存在上下文,并且您不会通过简单名称引用字段来执行任何非法赋值;相反,您满足了必须明确分配该字段的要求。

  • 使用静态初始化程序通过引用其限定名称来初始化 static final 字段是非法的,因为在引用它的静态属性时必须初始化类 (在您的情况下) , Test.A必须事先初始化,初始化完成后A被赋予默认值null

【讨论】:

    猜你喜欢
    • 2020-12-11
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多