我們接着上一章的代碼繼續來了解一下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生命周期中每個類如果存在,則不會重復加載。
- 在加載子類的時候會優先加載其父類。
- 類被加載的時候,其中的靜態代碼塊、靜態方法及靜態變量也會被加載。
- 在初始化某個類時,如果這個類的靜態代碼塊、靜態方法或靜態變量引用到了另一個類,則這個類也會被加載。
原文鏈接:https://www.cnblogs.com/zhixie/p/11766080.html