Java:静态最终字段以什么顺序初始化?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4446088/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java : in what order are static final fields initialized?
提问by sangfroid
Okay, so say I have a class that looks like this :
好的,假设我有一个看起来像这样的课程:
public class SignupServlet extends HttpServlet {
private static final Logger SERVLET_LOGGER=COMPANYLog.open(SignupServlet.class);
private static final ExceptionMessageHandler handler = new ExceptionMessageHandler();
private static final SignupServletObservableAgent signupObservableAgent =
new SignupServletObservableAgent(null, SERVLET_LOGGER);
}
Can I count on the class loader to initialize those fields in order, such that I can rely on SERVLET_LOGGER to be instantiated before signupObservableAgent?
我可以指望类加载器按顺序初始化这些字段,以便我可以依赖 SERVLET_LOGGER 在 signupObservableAgent 之前实例化吗?
回答by Laurence Gonsalves
Yes, they are initialized in the order in which they appear in the source. You can read all of the gory details in The Java Language Specification, §12.4.2. See step 9, which reads:
是的,它们按照它们在源代码中出现的顺序进行初始化。您可以阅读The Java Language Specification, §12.4.2中的所有血腥细节。参见第 9 步,内容如下:
... execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block, except that final class variables and fields of interfaces whose values are compile-time constants are initialized first ...
...以文本顺序执行类的类变量初始化器和静态初始化器,或接口的字段初始化器,就好像它们是单个块一样,除了最终类变量和其值是编译的接口字段外时间常数首先被初始化......
回答by Petro Semeniuk
I think that initialization of static fields could be re-ordered. At least that is how I understand JMM specification
我认为可以重新排序静态字段的初始化。至少我是这样理解JMM 规范的
There are a number of cases in which accesses to program variables (object instance fields, class static fields, and array elements) may appear to execute in a different order than was specified by the program.
在许多情况下,访问程序变量(对象实例字段、类静态字段和数组元素)的执行顺序可能与程序指定的顺序不同。
回答by Biswajit Sahoo
if sub class and super class is there.
如果有子类和超类。
- EX: 'A' : super class 'B' : sub class and it extends super class 'A'
- when B class loaded then A class also loads
- all static variables get memory with default value from 'A' and 'B' class
- then static members (static variable,static block) are executed in top to bottom order of 'A' class and then 'B' class in order they declared . finally main method executed from sub class automatically.
- EX: 'A' : 超类 'B' : 子类,它扩展了超类 'A'
- 当 B 类加载然后 A 类也加载
- 所有静态变量都从“A”和“B”类中获得具有默认值的内存
- 然后静态成员(静态变量,静态块)按照“A”类的从上到下的顺序执行,然后按照它们声明的顺序执行“B”类。最后自动从子类执行 main 方法。
回答by Alexey Pismenskiy
Not really answering the question, but asking more here -) . Just came across an interesting example with static field initialization order. Here is the example:
不是真的回答这个问题,而是在这里问更多 -) 。刚刚遇到一个带有静态字段初始化顺序的有趣示例。这是示例:
public class Foo {
private static final Long result = method1();
private static String string = "something";
private static Long method1() {
if (string == null) {
throw new IllegalStateException("BOOM");
}
return 1L;
}
public static void main(String[] args) {
System.out.println("here");
}
}
This will produce IllegalStateException. I understand that the sequence here is that first we evaluate "result" field which calls method1() and bypasses "string" value initialization. "string" is meant to be a constant, but I forgot to put a "final" modifier when wrote tests. But should such cases be handled in the runtime? Meaning when we invoke "if (string == null)" should JRE to be smart enough to go and verify that "string" has not been initialized and initialize it?
这将产生 IllegalStateException。我理解这里的顺序是首先我们评估调用 method1() 并绕过“字符串”值初始化的“结果”字段。“字符串”是一个常量,但我在编写测试时忘记添加“最终”修饰符。但是这种情况应该在运行时处理吗?意思是当我们调用“if (string == null)”时,JRE 是否应该足够聪明去验证“string”尚未初始化并初始化它?
回答by Siddhant Swami
This is a place where you can use a static block which would guarantee the sequence of execution.
这是一个可以使用静态块的地方,它可以保证执行的顺序。
public class SignupServlet extends HttpServlet {
private static final Logger SERVLET_LOGGER;
private static final ExceptionMessageHandler handler;
private static final SignupServletObservableAgent signupObservableAgent;
static {
SERVLET_LOGGER = COMPANYLog.open(SignupServlet.class);
handler = new ExceptionMessageHandler();
signupObservableAgent = new SignupServletObservableAgent(null, SERVLET_LOGGER);
}
}