2010-12-15 66 views
29

好了,所以说我有一个类,它看起来像这样:Java:以什么顺序初始化静态final字段?

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); 
} 

我能指望的类加载器,以初始化这些字段,这样我可以依靠SERVLET_LOGGER到signupObservableAgent之前被实例化?

回答

44

是的,它们按它们出现在源代码中的顺序进行初始化。您可以阅读The Java Language Specification, §12.4.2中的所有血淋淋的细节。见步骤9中,其内容为:

...执行任一类变量初始化和类的静态初始化,或接口的字段初始化,在文本顺序,就好像它们是单个块,不同之处这最后一类变量和它的值是编译时常首先被初始化界面领域...

+0

太棒了 - 谢谢! – sangfroid 2010-12-16 05:44:26

3

我觉得静态字段的初始化可能被重新排序。至少,这是我的理解JMM specification

有许多箱子在其访问到程序变量(对象的实例字段,类静态字段,和数组元素),比指定可能会出现在不同的顺序来执行由程序。

+3

这部分还指出“...并且b的值不取决于a的值,那么编译器可以自由地重新排序这些操作,...” – 2015-11-22 19:37:25

+0

引用是关于访问,而不是初始化。 – EJP 2017-01-29 14:04:02

1

如果子类和超类存在。

  1. EX: 'A':超类 'B':亚类,它扩展超类 'A'
  2. 当装B类,那么类还装载
  3. 所有静态变量获取内存默认值从'A'和'B'类
  4. 然后静态成员(静态变量,静态块)按照从上到下依次执行的'A'类和'B'类按顺序执行。 终于自动从子类执行的主要方法。
-1

这是一个可以使用静态块的地方,它可以保证执行的顺序。

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); 
    } 
} 
+0

毫无意义。订单已经保证。 – EJP 2017-01-29 14:04:52