Moh*_*rmi 5 java static initialization
我在这里读到这个问题:Java:静态最终字段以什么顺序初始化?
根据答案
“除了最终类变量和值为编译时常量的接口字段首先被初始化......”
我认为这是不正确的,因为以下操作会失败:
static {
String y = x;
}
public static final String x = "test";
Run Code Online (Sandbox Code Playgroud)
在静态块中,x不被识别。如果这个答案是正确的,有人可以发表评论吗?
初始化的顺序不会改变这样一个事实:在各种情况下,JLS 不允许您在声明变量之前引用变量。JLS\xc2\xa78.3.3中对此进行了描述:
\n\n\n\n\n其声明在使用后以文本形式出现的类变量的使用有时会受到限制,即使这些类变量在范围 (\xc2\xa76.3) 内。具体来说,如果满足以下所有条件,则为编译时错误:
\n\n\n
\n- \n
类或接口 C 中类变量的声明在使用类变量之后以文本形式出现;
- \n
在 C 的类变量初始值设定项或 C 的静态初始值设定项中使用简单名称;
- \n
使用不在作业的左侧;
- \n
C 是封闭使用的最内部类或接口。
这就是您的代码出现此编译错误的原因:
\n\n\n\n\n错误:非法前向引用
\n
作为常量变量的静态字段首先被初始化的语句确实在JLS\xc2\xa712.4.2中定义:
\n\n\n\n\n\n
\n\n- \n
否则,记录当前线程正在初始化 C 的 Class 对象,并释放 LC。
\n\n然后,初始化 C 的静态字段,它们是常量变量(\xc2\xa74.12.4、\xc2\xa78.3.2、\xc2\xa79.3.1)。
...
\n\n\n
\n- 接下来,按文本顺序执行类变量初始值设定项和类的静态初始值设定项,或接口的字段初始值设定项,就好像它们是单个块一样。
\n
如您所见,常量变量在步骤 6 中初始化,而其他变量在步骤 9 中初始化。
\n\n这演示了以下行为:
\n\npublic class Example {\n static String y;\n static {\n y = foo();\n }\n\n static String foo() {\n return x.toUpperCase();\n }\n\n public static final String x = "test";\n\n public static void main(String[] args) throws Exception {\n System.out.println(x);\n System.out.println(y);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n编译并输出:
\n\n\n测试\n测试\n\n\n
相反,如果您更改该x行,则它不再恒定:
public static final String x = Math.random() < 0.5 ? "test" : "ing";\nRun Code Online (Sandbox Code Playgroud)\n\n它可以编译,但随后失败,因为x从.nully = foo();
为了避免疑问:我不建议使用这样的方法来初始化字段。:-)
\n| 归档时间: |
|
| 查看次数: |
164 次 |
| 最近记录: |