【问题标题】:Why can't we set the value of static final variable in static block through class name [duplicate]为什么我们不能通过类名在静态块中设置静态最终变量的值[重复]
【发布时间】:2015-02-14 20:21:18
【问题描述】:

例如,考虑下面的代码快照:

public static final int a;
public static final int b;

static {
    a = 8;       // it's working
    Test.b = 10; // compilation error Test.b cannot be assigned. 
}

为什么我们不能在Test 类本身的静态块中使用Test.b = 10;?如果没有类名,它可以正常工作。

这背后有什么原因吗?

【问题讨论】:

  • 因为在静态初始化器中时您的类尚未初始化?也可能是因为 JLS 禁止它......
  • 您是否对“JLS 的哪一部分禁止这样做”或“为什么要这样设计语言”感兴趣?
  • 这里可能是错误的,但可能是因为您将Test.b 声明为final
  • @JSKNS:除了那个赋值之外,你现在在哪里看到它被初始化?如果您删除 Test. 部分,您会如何看待这种变化?
  • 您是否正在寻找一顶秘密的 Winter Bash 帽子来累积已删除的问题答案...?

标签: java static final static-block


【解决方案1】:

静态最终变量必须在使用前进行初始化。它可以在声明时直接初始化,也可以在静态块中初始化。

但是当您使用class.var = x 时,它不会被视为初始化,而是被视为分配。

使用 JDK 7,错误是 无法为最终变量赋值

这就解释了为什么删除 final 关键字会起作用

class Test {

    static final int a = 2; // initialization at declaration time
    static final int b;
    static final int c;

    static {
        b = 4;  // initialization in static block
        Test.c = 6; // error : cannot assign a value to final variable c
    }
    ...

}

编辑

在 JLS 中,正确的初始化词是确定的赋值

从 JLS 中提取:

对于局部变量或空白最终字段 x 的每次访问,x 必须是肯定的 在访问之前分配,或者发生编译时错误。

同样,每个空白的 final 变量最多只能赋值一次;一定是 当分配给它时肯定是未分配的。

当且仅当 变量(或者,对于一个字段,它的简单名称由 this 限定) 出现在左侧 赋值运算符的一侧。

每次赋值给一个空白的 final 变量,这个变量必须是肯定的 在赋值之前未赋值,或者发生编译时错误。

强调我的,但我认为这是错误的真正原因。

【讨论】:

  • 我不认为这是完全正确的,尽管它必须沿着正确的路线。这表示您不能分配给一个空白的 final 变量,除非它当时肯定是未分配的,但它肯定是未分配的。在我看来,这并没有违反您引用的内容。
  • @chiastic-security : 我不是真正的律师,英语不是我的第一语言,因为我认为这里的重要词是 simple name 因为@987654324 @ 不是一个简单的名字。
  • 是的,这句话很重要,但它只是说Test.b = 10 不是“这样的分配”,也就是说,这段代码不在 JLS 的这一位视图中。
  • @chiastic-security :你是对的。我忘记了段落的第一行声明对于局部变量或空白最终字段x的每次访问,必须在访问之前明确分配x,否则会发生编译时错误。。已添加。
  • @chiastic-security :正如我所说,英语不是我的第一语言,我认为 access 可以是写也可以是读错误。
猜你喜欢
  • 2018-11-07
  • 2020-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-05
  • 2012-11-26
相关资源
最近更新 更多