我們接着上一章的代碼繼續來了解一下java類是在什么時候加載的。在開始驗證之前,我們現在IDEA做如下配置。
-XX:+TraceClassLoading 監控類的加載

我們新建了一個TestController 來測試類的加載時機,代碼如下:
@RestController
public class TestController {
@RequestMapping("/newInstance")
public String newInstance(){
Father father = new Father();
return "";
}
@RequestMapping("/newChildrenInstance")
public String childrenInstance(){
Children children = new Children();
return "";
}
@RequestMapping("/staticField")
public String staticField(){
String staticValue = Children.staticValue;
return "";
}
@RequestMapping("staticMethod")
public String staticMethod(){
String bed = Children.bed();
return "";
}
@RequestMapping("classForName")
public String classForName() throws Exception {
Class.forName("com.zhixie.jvmclassload.demo.Children");
return "";
}
}
一、定義了main的類,啟動main方法時該類會被加載
本次驗證采用的是springboot 2.2.0版本。當運行啟動類的時候,我們可以看到只有啟動類被加載了。

二、創建類的實例,即new對象的時候
1、創建父類的實例

此時被加載的類有Father及Field類,我們重啟服務,然后去訪問創建子類的實例。為什么要重啟呢?因為每個類在虛擬機生命周期中如果存在,則不會重復加載。不重啟的話,看不到我們想要的效果。
2、創建子類的實例

在創建子類實例的時候,在加載子類之前會優先加載其父類。
三、訪問類的靜態方法

四、訪問類的靜態變量

五、反射 Class.forName()

總結
- java類在以上五種情況下會被加載。
- 在jvm生命周期中每個類如果存在,則不會重復加載。
- 在加載子類的時候會優先加載其父類。
- 類被加載的時候,其中的靜態代碼塊、靜態方法及靜態變量也會被加載。
- 在初始化某個類時,如果這個類的靜態代碼塊、靜態方法或靜態變量引用到了另一個類,則這個類也會被加載。
如果文章對您有幫助,請記得點贊關注喲~
歡迎大家關注我的公眾號<情系IT>,每日技術推送文章供大家學習參考。
