Java類初始化時機測試方法解析
<clinit>()方法
Java 類加載的初始化過程中,編譯器按語句在源文件中出現(xiàn)的順序,依次自動收集類中的所有類變量的賦值動作和靜態(tài)代碼塊中的語句合并產(chǎn)生方法。 如果類中沒有靜態(tài)語句和靜態(tài)代碼塊,那可以不生成<clinit>() 方法。
并且 <clinit>() 不需要顯式調(diào)用父類(接口除外,接口不需要調(diào)用父接口的初始化方法,只有使用到父接口中的靜態(tài)變量時才需要調(diào)用)的初始化方法 <clinit>(),虛擬機會保證在子類的 <clinit>() 方法執(zhí)行之前,父類的 <clinit>() 方法已經(jīng)執(zhí)行完畢(所以java.lang.Object 類總是第一個被加載)

準(zhǔn)備父類和子類
class Father {
static int father_a = 1;
static {
System.out.println("父類靜態(tài)代碼塊執(zhí)行");
}
static class StaticInnerClass {
static {
System.out.println("靜態(tài)內(nèi)部類靜態(tài)代碼塊執(zhí)行");
}
}
}
class Son extends Father {
static {
System.out.println("子類靜態(tài)代碼塊執(zhí)行");
son_a = 300;
}
static int son_a = 100;
static final int M = 1;
}
Main方法:
1:父類沒有被引用但是會被先加載
new Son();

2:反射也會產(chǎn)生主動引用:
Class a = Class.forName("clinit.Son");
(運行結(jié)果同1)
3:子類使用父類靜態(tài)變量或方法不會產(chǎn)生類的引用
System.out.println("Father.a = " + Son.father_a);

4:通過類創(chuàng)建數(shù)組不會加載類(只是開辟一塊空間)
Son[] sons = new Son[8];

5:使用常量不會加載父類和之類(常量在Linking階段就保存在常量池當(dāng)中了)
System.out.println("Son.CONST = " + Son.CONST);

6:引用靜態(tài)內(nèi)部類不會加載外部類(應(yīng)用于單例模式)
new Father.StaticInnerClass();

代碼總結(jié):
public static void main(String[] args) throws Exception {
// 1.父類沒有被引用但是會被先加載
// new Son();
// 2.反射會產(chǎn)生主動引用
// Class a = Class.forName("clinit.Son");
// 3.子類使用父類靜態(tài)變量或方法不會產(chǎn)生類的引用
// System.out.println("Father.a = " + Son.father_a);
// 4.通過類創(chuàng)建數(shù)組不會加載類(只是開辟一塊空間)
// Son[] sons = new Son[8];
// 5.使用常量不會加載父類和之類(常量在Linking階段就保存在常量池當(dāng)中了)
// System.out.println("Son.CONST = " + Son.CONST);
// 6.引用靜態(tài)內(nèi)部類不會加載外部類(應(yīng)用于單例模式)
// new Son.StaticInnerClass();
}
}
PS:由于是按出現(xiàn)的順序執(zhí)行的,為了避免不必要的麻煩,應(yīng)盡量把靜態(tài)變量寫在靜態(tài)代碼塊之前
public class Test {
public static void main(String[] args) {
System.out.println("a = " + cls.a);
}
}
class cls {
static int a = 10;8 static { a = 20; }9 }

如果 調(diào)換順序輸出結(jié)果將是 a = 10
class cls {
static { a = 20; }
static int a = 10;
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
springCloud服務(wù)注冊Eureka實現(xiàn)過程圖解
這篇文章主要介紹了springCloud服務(wù)注冊Eureka實現(xiàn)過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-04-04
Mybatis-Plus條件構(gòu)造器select方法返回指定字段方式
這篇文章主要介紹了Mybatis-Plus條件構(gòu)造器select方法返回指定字段方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
SpringMVC中DispatcherServlet的HandlerMapping詳解
這篇文章主要介紹了SpringMVC中DispatcherServlet的HandlerMapping詳解,上回說的Handler,我們說是處理特定請求的,也就是說,不是所有的請求都能處理,那么問題來了,我們怎知道哪個請求是由哪個Handler處理的呢,需要的朋友可以參考下2023-10-10
Spring Boot2.x集成JPA快速開發(fā)的示例代碼
這篇文章主要介紹了Spring Boot2.x集成JPA快速開發(fā),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
java訪問者模式的靜態(tài)動態(tài)及偽動態(tài)分派徹底理解
這篇文章主要為大家介紹了java訪問者模式的靜態(tài)動態(tài)及偽動態(tài)分派徹底理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06

