Java類的初始化順序知識(shí)點(diǎn)總結(jié)
對(duì)于靜態(tài)變量、靜態(tài)初始化塊、變量、初始化塊、構(gòu)造器,它們的初始化順序依次是(靜態(tài)變量、靜態(tài)初始化塊)>(變量、初始化塊)>構(gòu)造器。
初始化順序圖示:


我們也可以通過下面的測(cè)試代碼來驗(yàn)證這一點(diǎn):
package com.trs.oop;
/**
* 類的初始化順序
* 靜態(tài)變量->靜態(tài)初始化塊->變量->初始化塊->構(gòu)造器
* @author xiayunan
* @date 2018年7月5日
*
*/
public class InitialOrderTest {
// 靜態(tài)變量
public static String staticField = "靜態(tài)變量";
// 變量
public String field = "變量";
// 靜態(tài)初始化塊
static {
System.out.println(staticField);
System.out.println("靜態(tài)初始化塊");
}
// 初始化塊
{
System.out.println(field);
System.out.println("初始化塊");
}
// 構(gòu)造器
public InitialOrderTest() {
System.out.println("構(gòu)造器");
}
public static void main(String[] args) {
new InitialOrderTest();
}
}
運(yùn)行結(jié)果:

而對(duì)于繼承的情況初始化順序又會(huì)是怎么樣的呢?請(qǐng)看下面示例代碼:
package com.trs.oop;
/**
* 有繼承關(guān)系的類初始化順序
* @author xiayunan
* @date 2018年7月5日
*
*/
class Parent {
// 靜態(tài)變量
public static String p_StaticField = "父類--靜態(tài)變量";
protected int i = 1;
protected int j = 8;
// 變量
public String p_Field = "父類--變量";
// 靜態(tài)初始化塊
static {
System.out.println(p_StaticField);
System.out.println("父類--靜態(tài)初始化塊");
}
// 初始化塊
{
System.out.println(p_Field);
System.out.println("父類--初始化塊");
}
// 構(gòu)造器
public Parent() {
System.out.println("父類--構(gòu)造器");
System.out.println("i=" + i + ", j=" + j);
j = 9;
}
}
public class SubClass extends Parent {
// 靜態(tài)變量
public static String s_StaticField = "子類--靜態(tài)變量";
// 變量
public String s_Field = "子類--變量";
// 靜態(tài)初始化塊
static {
System.out.println(s_StaticField);
System.out.println("子類--靜態(tài)初始化塊");
}
// 初始化塊
{
System.out.println(s_Field);
System.out.println("子類--初始化塊");
}
// 構(gòu)造器
public SubClass() {
System.out.println("子類--構(gòu)造器");
System.out.println("i=" + i + ",j=" + j);
}
// 程序入口
public static void main(String[] args) {
new SubClass();
}
}
運(yùn)行結(jié)果:

現(xiàn)在,結(jié)果已經(jīng)不言自明了。子類的靜態(tài)變量和靜態(tài)初始化塊的初始化是在父類的變量、初始化塊和構(gòu)造器初始化之前就完成了。
靜態(tài)變量、靜態(tài)初始化塊,變量、初始化塊初始化了順序取決于它們?cè)陬愔谐霈F(xiàn)的先后順序。
執(zhí)行過程分析
(1)訪問SubClass.main(),(這是一個(gè)static方法),于是裝載器就會(huì)為你尋找已經(jīng)編譯的SubClass類的代碼(也就是SubClass.class文件)。在裝載的過程中,裝載器注意到它有一個(gè)基類(也就是extends所要表示的意思),于是它再裝載基類。不管你創(chuàng)不創(chuàng)建基類對(duì)象,這個(gè)過程總會(huì)發(fā)生。如果基類還有基類,那么第二個(gè)基類也會(huì)被裝載,依此類推。
(2)執(zhí)行根基類的static初始化,然后是下一個(gè)派生類的static初始化,依此類推。這個(gè)順序非常重要,因?yàn)榕缮惖摹皊tatic初始化”有可能要依賴基類成員的正確初始化。
(3)當(dāng)所有必要的類都已經(jīng)裝載結(jié)束,開始執(zhí)行main()方法體,并用new SubClass()創(chuàng)建對(duì)象。
(4)類SubClass存在父類,則調(diào)用父類的構(gòu)造函數(shù),你可以使用super來指定調(diào)用哪個(gè)構(gòu)造函數(shù)(也就是Beetle()構(gòu)造函數(shù)所做的第一件事)。
基類的構(gòu)造過程以及構(gòu)造順序,同派生類的相同。首先基類中各個(gè)變量按照字面順序進(jìn)行初始化,然后執(zhí)行基類的構(gòu)造函數(shù)的其余部分。
(5)對(duì)子類成員數(shù)據(jù)按照它們聲明的順序初始化,執(zhí)行子類構(gòu)造函數(shù)的其余部分。
以上就是本次腳本之家介紹的全部相關(guān)知識(shí)點(diǎn),感謝大家的學(xué)習(xí)和支持。
相關(guān)文章
Java使用MessageFormat應(yīng)注意的問題
這篇文章主要介紹了Java使用MessageFormat應(yīng)注意的問題,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-06-06
Feign調(diào)用中的兩種Header傳參方式小結(jié)
這篇文章主要介紹了Feign調(diào)用中的兩種Header傳參方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
WebDriver實(shí)現(xiàn)自動(dòng)化打開IE中的google網(wǎng)頁并實(shí)現(xiàn)搜索
這篇文章主要介紹了WebDriver實(shí)現(xiàn)自動(dòng)化打開IE中的google網(wǎng)頁并實(shí)現(xiàn)搜索,需要的朋友可以參考下2014-04-04
springboot自帶的緩存@EnableCaching用法
這篇文章主要介紹了springboot自帶的緩存@EnableCaching用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
基于常用json框架介紹和Jackson返回結(jié)果處理方式
這篇文章主要介紹了基于常用json框架介紹和Jackson返回結(jié)果處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09

