類別何時載入
#類別的載入是透過類別載入器(Classloader)完成的,它既可以是餓漢式[eagerly load](只要有其它類引用了它就加載)加載類,也可以是懶加載[lazy load](等到類初始化發生的時候才加載)。 (建議學習:java課程)
不過我相信這跟不同的JVM實作有關,然而他又是受JLS保證的(當有靜態初始化需求的時候才被加載)。
類別何時初始化
載入完類別後,類別的初始化就會發生,表示它會初始化所有類別靜態成員,以下情況一個類別被初始化:
實例透過使用new()關鍵字建立或使用class.forName()反射,但它有可能導致ClassNotFoundException。
類別的靜態方法被呼叫
類別的靜態域被賦值
靜態域被訪問,而且它不是常數
在頂層類別中執行assert語句
反射同樣可以使類別初始化,例如java.lang.reflect套件下面的某些方法,JLS嚴格的說明:一個類別不會被任何除以上之外的原因初始化。
類別是如何被初始化的
現在我們知道何時觸發類別的初始化了,他精確地寫在Java語言規格中。但了解清楚域(fields,靜態的還是非靜態的)、塊(block靜態的還是非靜態的)、不同類(子類和超類)和不同的接口(子接口,實現類和超接口)的初始化順序也很重要類別。
事實上很多核心Java面試題和SCJP問題都是基於這些概念,以下是類別初始化的一些規則:
類別從頂至底的順序初始化,所以聲明在頂部的字段的早於底部的字段初始化
超類早於子類和衍生類的初始化
如果類的初始化是由於訪問靜態域而觸發,那麼只有宣告靜態域的類別才會被初始化,而不會觸發超類別的初始化或子類別的初始化即使靜態域被子類別或子介面或它的實作類別所引用。
介面初始化不會導致父介面的初始化。
靜態域的初始化是在類別的靜態初始化期間,非靜態域的初始化時在類別的實例建立期間。這意味著這靜態域初始化在非靜態域之前。
非靜態域透過建構器初始化,子類別在做任何初始化之前建構器會隱含地呼叫父類別的建構器,他保證了非靜態或實例變數(父類別)初始化早於子類別
以上是java類別在什麼時候載入的詳細內容。更多資訊請關注PHP中文網其他相關文章!