2009-11-19 27 views
6

想象一下您可以在課堂上找到的具有最多功能的Java類。例如:它從另一個類繼承,實現了幾個接口,包括一些'靜態final'常量,一些最終常量,一些靜態變量,實例變量,一個靜態塊,一個未命名的代碼塊(只是{}中的代碼)構造函數,方法等。在JVM中加載類時,以何種順序初始化類的不同部分?

當有問題的類首次加載到JVM中時,類的各個部分按什麼順序初始化或加載到JVM中? JVM中的調用堆棧對於加載看起來如何?假設這裏只有一個類加載器在工作。

這回到Java的絕對基礎/內部,但我還沒有找到一篇很好的文章來解釋正確的順序。

回答

1

JLS怎麼樣,具體是12.4節?

+0

真的很順利...... :)希望我有正確的谷歌搜索詞去JLS! 也只是讓我吃了一驚,我可能已經能夠通過eclipse調試器運行這個... :( – Thimmayya 2009-11-19 07:11:40

3

這可能在部分中描述2.17.4 of the JVMS 5.0/6

2.17.4初始化

一類的初始化包括:

  • 執行其靜態初始化(§2.11)和
  • 在類中聲明的靜態字段(§2.9.2)的初始值設定項。

接口的初始化包括執行接口(§2.13.3.1)中聲明的字段的初始值設定項。

在類或接口初始化之前,它的直接超類必須被初始化,但是類實現的接口不需要被初始化。同樣,接口的超級接口在初始化之前不需要初始化。

  • T是一個類並且創建T的實例:

    類或接口類型T將下列情況之一發生之前​​立即被初始化。

  • T是一個類,T的一個靜態方法被調用。
  • 使用或分配T的非恆定靜態字段。常量字段是(明確或隱含地)最終和靜態的字段,並且是用編譯時常量表達式的值初始化的。對這種字段的引用必須在編譯時解析爲編譯時常量值的副本,所以這種字段的使用永遠不會導致初始化。

調用庫類中的某些方法(§3.12)也會導致類或接口初始化。有關詳細信息,請參閱Java 2平臺的類庫規範(例如,類類和包java.lang.reflect)。

這裏的意圖是,一個類型有一組初始化器,它將其置於一致狀態,並且此狀態是其他類所觀察到的第一個狀態。靜態初始化器和類變量初始化器按文本順序執行,並且可能不會引用聲明在類中聲明的類變量,其聲明在使用後以文本形式出現,即使這些類變量在範圍內。此限制旨在在編譯時檢測大多數循環或其他格式不正確的初始化。

在類或接口被初始化之前,如果它的父類先前沒有被初始化過,它的父類會被初始化。


Initialization in JVMS 8 is in Chapter 5.5

一個類或接口的初始化的更新的版本包括執行其類或接口初始化方法(§2.9)的。

類或接口可以僅作爲一個結果被初始化:

  • 引用的類或接口的Java虛擬機指令newgetstaticputstatic任一項,或invokestatic的執行(§new§getstatic,§putstatic§invokestatic)。
    所有這些指令直接或通過字段引用或方法引用間接引用類。
    執行新指令後,如果尚未初始化已引用的類或接口,則會對其進行初始化。
    執行getstatic,putstaticinvokestatic指令後,聲明已解析字段或方法的類或接口將在其尚未初始化的情況下進行初始化。
  • 一個java.lang.invoke.MethodHandle實例,它是由Java虛擬機(§5.4.3.5)和其中方法手柄的分辨率的結果的第一次調用具有種2(REF_getStatic),4(REF_putStatic),6(REF_invokeStatic),或8(REF_newInvokeSpecial)。
  • 在類庫(§2.12)中調用某些反射方法,例如,類Class或包java.lang.reflect
  • 其中一個子類的初始化。
  • 它被指定爲Java虛擬機啓動時的初始類(§5.2)。

之前初始化,一個類或接口必須鏈接,即,覈實,製備,並且任選地解決

因爲Java虛擬機是多線程的,所以類或接口的初始化需要仔細的同步,因爲其他線程可能試圖同時初始化相同的類或接口。
也可能會初始化類或接口,可能會遞歸地請求初始化該類或接口的一部分。

Java虛擬機的實現負責照顧同步和遞歸初始化,方法是使用以下過程。
它假定Class對象已經驗證和準備,該Class對象包含狀態表示的四種情況之一:

  • Class對象進行驗證和準備,但沒有初始化。
  • 這個Class對象正在被某個特定的線程初始化。
  • Class對象已完全初始化並可供使用。
  • Class對象處於錯誤狀態,可能是因爲初始化嘗試失敗。
+0

+1爲您的更新。 – sunleo 2014-09-02 13:14:10