【问题标题】:Static final field initialization from static initializer来自静态初始化器的静态最终字段初始化
【发布时间】:2014-10-06 17:28:30
【问题描述】:

为什么不能使用声明类作为限定符(以静态方式)从相应的静态初始化器访问静态最终字段?

起初,我以为这是一个 Eclipse 错误:

我还缺乏一些知识,因为静态初始化器不是我的日常工作。但是你瞧,这在没有类限定符的情况下可以正常工作:

为了完成我的测试系列,我在 bash 中试了一下:

导致同样的结果。

这就引出了最后一个问题:

从静态初始化块访问静态最终字段时,是否有任何理由禁止类限定符? 因为声明类之前没有初始化?

【问题讨论】:

标签: java static-initializer


【解决方案1】:

实际上,您可以从静态初始化器初始化静态字段。

但我认为(我不确定),您遇到了另一个问题。这里的问题是您(根据编译器)试图分配一个 final 字段。但是,您的真正意图不是分配它。您正在尝试初始化它。但是编译器没有得到这个。

当您调用 Test.I 之类的东西时,编译器会认为您正在尝试修改它之前可能已初始化的静态变量(即来自静态初始化程序)。编译器并不那么聪明,无法看到您实际上是在初始化变量,它只是解释您正在从一个类中分配一个静态变量,无论是 Test或者是Foo

但是,如果您在没有 类限定符 的情况下调用它,编译器就会知道您正在尝试修改自己的静态变量,并且在静态初始化程序中,因此该操作对于 final 字段。

请,我希望我说得足够清楚,请注意,我不确定这种行为。

【讨论】:

    【解决方案2】:

    为了在初始化块中初始化最终变量,应该使用变量的简单名称。即没有任何限定符的变量名。

    在java语言规范中有如下说明

    “同样,每个空白的 final 变量最多只能赋值一次;当对它进行赋值时,它肯定是未赋值的。这样的赋值被定义为当且仅当变量的简单名称之一时才会发生, 或其简单名称由此限定,出现在赋值运算符的左侧。Java 编译器必须执行特定的保守流分析,以确保对于空白最终变量的每个赋值,变量在赋值之前肯定是未赋值的;否则一定会出现编译时错误。”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-13
      • 1970-01-01
      • 2011-02-15
      • 1970-01-01
      • 1970-01-01
      • 2013-09-30
      • 1970-01-01
      • 2016-12-30
      相关资源
      最近更新 更多