Java類加載順序

先看一段代碼:

public class Text {
    public static int k = 0;
    public static Text t1 = new Text("t1");
    public static Text t2 = new Text("t2");
    public static int i = print("i");
    public static int n = 99;
    public int j = print("j");

    {
        print("構(gòu)造塊");
    }
    static {
        print("靜態(tài)塊");
    }

    public Text(String str) {
        System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);
        ++i;
        ++n;
    }

    public static int print(String str) {
        System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);
        ++n;
        return ++i;
    }

    public static void main(String args[]) {
        Text t = new Text("init");
    }
}

輸出結(jié)果為:
1:j i=0 n=0
2:構(gòu)造塊 i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:構(gòu)造塊 i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:靜態(tài)塊 i=7 n=99
9:j i=8 n=100
10:構(gòu)造塊 i=9 n=101
11:init i=10 n=102

加載過(guò)程分析

執(zhí)行main時(shí),先加載所在類,聲明靜態(tài)變量,并初始化靜態(tài)變量執(zhí)行靜態(tài)代碼塊(按順序執(zhí)行)

初始化到t1時(shí),暫停類加載,先實(shí)例化,此時(shí)k=0,而i,n都未初始化,系統(tǒng)默認(rèn)值為0
初始化j時(shí),k自增為1,i,n為0,輸出“1:j i=0 n=0”,n,i自增為1
執(zhí)行代碼塊,輸出“2:構(gòu)造塊 i=1 n=1”,n,i自增為2
執(zhí)行構(gòu)造函數(shù),輸出“3:t1 i=2 n=2”,n,i自增為3

初始化到t2時(shí),暫停類加載,先實(shí)例化,此時(shí)k=3,i,n都還未初始化,但已自增為3
初始化j時(shí),k自增為4,i,n未初始化為3,輸出“4:j i=3 n=3”,n,i自增為4
執(zhí)行代碼塊,輸出“5:構(gòu)造塊 i=4 n=4”,n,i自增為5
執(zhí)行構(gòu)造函數(shù),輸出“6:t2 i=5 n=5”,n,i自增為6

初始化i,輸出“7:i i=6 n=6”,n,i自增為7,返回自增后的i賦值給i
初始化n,賦值99
執(zhí)行靜態(tài)塊,輸出“8:靜態(tài)塊 i=7 n=99”,i自增為8,n自增為100

完成類加載,執(zhí)行Text t = new Text("init");
初始化成員變量j,輸出9:j i=8 n=100
調(diào)用構(gòu)造塊和構(gòu)造方法,輸出 10:構(gòu)造塊 i=9 n=101
11:init i=10 n=102

涉及要點(diǎn)

1.類加載過(guò)程
加載某類前先加載其父類
加載某類時(shí),先聲明靜態(tài)成員變量,初始化為默認(rèn)值,再初始化靜態(tài)成員變量執(zhí)行靜態(tài)代碼塊
初始化靜態(tài)成員變量執(zhí)行靜態(tài)代碼塊時(shí),是按順序執(zhí)行(初始化靜態(tài)成員變量的本質(zhì)就是靜態(tài)代碼塊)

2.實(shí)例化過(guò)程
對(duì)某類實(shí)例化前,先對(duì)其父類進(jìn)行實(shí)例化
實(shí)例化某類時(shí),先聲明成員變量,初始化為默認(rèn)值,再初始化成員變量執(zhí)行代碼塊
初始化成員變量執(zhí)行代碼塊時(shí),是按順序執(zhí)行

3.在某類加載過(guò)程中調(diào)用了本類實(shí)例化過(guò)程(如new了本類對(duì)象),則會(huì)暫停類加載過(guò)程先執(zhí)行實(shí)例化過(guò)程,執(zhí)行完畢再回到類加載過(guò)程

類的主動(dòng)使用與被動(dòng)使用

主動(dòng)使用例子:

1):最為常用的new一個(gè)類的實(shí)例對(duì)象
2):直接調(diào)用類的靜態(tài)方法。
3):操作該類或接口中聲明的非編譯期常量靜態(tài)字段
4):反射調(diào)用一個(gè)類的方法。
5):初始化一個(gè)類的子類的時(shí)候,父類也相當(dāng)于被程序主動(dòng)調(diào)用了
(如果調(diào)用子類的靜態(tài)變量是從父類繼承過(guò)來(lái)并沒(méi)有復(fù)寫(xiě)的,那么也就相當(dāng)于只用到了父類的東東,和子類無(wú)關(guān),
所以這個(gè)時(shí)候子類不需要進(jìn)行類初始化)。
6):直接運(yùn)行一個(gè)main函數(shù)入口的類。

所有的JVM實(shí)現(xiàn),在首次主動(dòng)使用某類的時(shí)候才會(huì)加載該類。

被動(dòng)使用例子:

1):子類調(diào)用父類的靜態(tài)變量,子類不會(huì)被初始化。只有父類被初始化。對(duì)于靜態(tài)字段,只有直接定義這個(gè)字段的類才會(huì)被初始化.
2):通過(guò)數(shù)組定義來(lái)引用類,不會(huì)觸發(fā)類的初始化,如SubClass[] sca = new SubClass[10];
3):訪問(wèn)類的編譯期常量,不會(huì)初始化類

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 很長(zhǎng)時(shí)間沒(méi)看這方面的內(nèi)容了,寫(xiě)篇文章讓自己牢記一下,順便分享一下。 首先,寫(xiě)代碼以便檢驗(yàn)結(jié)果。測(cè)試代碼: 子類代碼...
    沈子羽閱讀 5,541評(píng)論 2 7
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,853評(píng)論 18 399
  • Win7下如何打開(kāi)DOS控制臺(tái)? a:開(kāi)始--所有程序--附件--命令提示符 b:開(kāi)始--搜索程序和文件--cmd...
    逍遙嘆6閱讀 1,723評(píng)論 4 12
  • 曾有一段時(shí)間,身心俱疲,充滿了煩惱,很想知道怎樣才能讓自己每天都開(kāi)心快樂(lè)的生活。我偶然間拜讀了伯特蘭·亞瑟·威...
    星空道德閱讀 6,003評(píng)論 4 20
  • 2017年8月6日晚 今晚我買(mǎi)醉了,喝醉了我才知道自己永遠(yuǎn)都忘不了你,七年,我還那么貪念你的臂彎,我知道我對(duì)不起你...
    臻臻的心閱讀 247評(píng)論 0 0

友情鏈接更多精彩內(nèi)容