2010-12-15 64 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