最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

分析Java中的類加載問題

 更新時間:2021年06月25日 08:46:41   作者:華為云開發(fā)者社區(qū)  
很多時候提到類加載,大家總是沒法馬上回憶起順序,這篇文章會用一個例子為你把類加載的諸多問題一次性澄清

一、Java類的加載順序

引用1個網(wǎng)上的經(jīng)典例子,并做稍許改動,以便大家更好地理解。

public class Animal {
    private int i = test();
    private static int j  = method();
    static {
        System.out.println("a");
    }
    Animal(){
        System.out.println("b");
    }
    {
        System.out.println("c");
    }
    public int test(){
        System.out.println("d");
        return 1;
    }
    public static int method(){
        System.out.println("e");
        return 1;
    }
}
public class Dog extends Animal{
    {
        System.out.println("h");
    }
    private int i = test();
    static {
        System.out.println("f");
    }
    private static int j  = method();

    Dog(){
        System.out.println("g");
    }
    public int test(){
        System.out.println("i");
        return 1;
    }
    public static int method(){
        System.out.println("j");
        return 1;
    }
    public static void main(String[] args) {
        Dog dog = new Dog();
        System.out.println();
        Dog dog1 = new Dog();
    }
}

執(zhí)行這段main程序,會輸出什么?

答案是

eafjicbhig
icbhig

為了方便大家一個個細節(jié)去理解, 我換一種方式去提問。

Q: 什么時候會進行靜態(tài)變量的賦值和靜態(tài)代碼塊的執(zhí)行?

A:

  • 第一次創(chuàng)建某個類或者某個類的子類的實例
  • 訪問類的靜態(tài)變量、調(diào)用類的靜態(tài)方法
  • 使用反射方法forName
  • 調(diào)用主類的main方法(本例子的第一次靜態(tài)初始化其實屬于這個情況,調(diào)用了Dog的main方法)

注: 類初始化只會進行一次, 上面任何一種情況觸發(fā)后,之后都不會再引起類初始化操作。

Q:初始化某個子類時,也會對父類做靜態(tài)初始化嗎?順序呢?

A:如果父類之前沒有被靜態(tài)初始化過,那就會進行, 且順序是先父類再子類。 后面的非靜態(tài)成員初始化也是如此。
所以會先輸出eafj。

Q: 為什么父類的method不會被子類的method重寫?

A: 靜態(tài)方法是類方法,不會被子類重寫。畢竟類方法調(diào)用時,是必定帶上類名的。

Q: 為什么第一個輸出的是e而不是a?

A: 因為類變量的顯示賦值代碼和靜態(tài)代碼塊代碼按照從上到下的順序執(zhí)行。

Animal的靜態(tài)初始化過程中,method的調(diào)用在static代碼塊之前,所以先輸出e再輸出a。

而Dog的靜態(tài)初始化過程中,method的調(diào)用在static代碼塊之后,因此先輸出f,再輸出j

Q: 沒有在子類的構(gòu)造器中調(diào)用super()時,也會進行父類對象的實例化嗎?

A: 會的。會自動調(diào)用父類的默認構(gòu)造器。 super()主要是用于需要調(diào)用父類的特殊構(gòu)造器的情況。
因此會先進行Animal的對象實例化,再進行Dog的對象實例化

Q: 構(gòu)造方法、成員顯示賦值、非靜態(tài)代碼塊(即輸出c和h的那2句)的順序是什么?

A:

1.成員顯示賦值、非靜態(tài)代碼塊(按定義順序)

2.構(gòu)造方法

因此Animal的實例化過程輸出icb(如果對輸出i有疑問,見下面一題)
接著進行Dog的實例化,輸出hig

Q: 為什么Animal實例化時, i=test()中輸出的是i而不是d?

A:因為你真正創(chuàng)建的是Dog子類,Dog子類中的test()方法由于簽名和父類test方法一致,因此test方法被重寫了。
此時即使在父類中調(diào)用,也還是用使用子類Dog的方法。除非你new的是Animal。

Q: 同上題, 如果test方法都是private或者final屬性, 那么上題的情況會有變化嗎??

A:

因為private和final方法是不能被子類重寫的。
所以Animal實例化時,i=test輸出d。

總結(jié)一下順序:

1.父類靜態(tài)變量顯式賦值、父類靜態(tài)代碼塊(按定義順序)

2.子類靜態(tài)變量顯式賦值、子類靜態(tài)代碼塊(按定義順序)

3.父類非靜態(tài)變量顯式賦值(父類實例成員變量)、父類非靜態(tài)代碼塊(按定義順序)

4.父類構(gòu)造函數(shù)

5.子類非靜態(tài)變量(子類實例成員變量)、子類非靜態(tài)代碼塊(按定義順序)

6.子類構(gòu)造函數(shù)。

二、類加載過程

Q:類加載的3個必經(jīng)階段是:

A:

1.加載(類加載器讀取二進制字節(jié)流,生成java類對象)

2.鏈接(驗證,分配靜態(tài)域初始零值)

3.初始化(前面的題目講的其實就是初始化時的順序)

更詳細的如下:

三、被動引用中和類靜態(tài)初始化的關(guān)系

Q:new某個類的數(shù)組時,會引發(fā)類初始化嗎?

像下面輸出什么

public class Test {
    static class A{
        public static int a = 1;
        static{
            System.out.println("initA");
        }
    }
 
    public static void main(String[] args) {
        A[] as = new A[5];
    }
}

A:

new數(shù)組時,不會引發(fā)類初始化。
什么都不輸出。

Q:引用類的final靜態(tài)字段,會引發(fā)類初始化嗎?

像下面輸出什么?

public class Test {
    static class A{
        public static final int a = 1;
        static{
            System.out.println("initA");
        }
    }

    public static void main(String[] args) {
        System.out.println("A.a=" + A.a);
    }
}

A: 不會引發(fā)。

不會輸出initA。 去掉final就會引發(fā)了。
(注意這里必須是基本類型常量, 如果是引用類型產(chǎn)量,則會引發(fā)類初始化)

Q:子類引用了父類的靜態(tài)成員,此時子類會做類初始化嘛?

如下會輸出什么

public class Test {
    static class A{
        public static int a = 1;
        static{
            System.out.println("initA");
        }
    }

    static class B extends A{
        static {
            System.out.println("initB");
        }
    }

    public static void main(String[] args) {
        System.out.println("B.a=" + B.a);
    }
}

A:

子類不會初始化。
打印initA,卻不會打印initB。

四、類加載器雙親委派

類加載時的雙親委派模型,不知道能怎么出題。。。反正就記得優(yōu)先去父類加載器中看類是否能加載。

Bootsrap不是ClassLoader的子類,他是C++編寫的。
而ExtClassLoader和AppClassLoader都是繼承自ClassLoader的

Q:java中, 是否類和接口的包名和名字相同, 那么就一定是同一個類或者接口?

A:錯誤。

1個jvm中, 類和接口的唯一性由二進制名稱以及它的定義類加載器共同決定。
因此2個不同的加載器加載出來相同的類或接口時, 實際上是不同的。

以上就是分析Java中的類加載問題的詳細內(nèi)容,更多關(guān)于Java 類加載的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 如何利用泛型封裝通用的service層

    如何利用泛型封裝通用的service層

    這篇文章主要介紹了如何利用泛型封裝通用的service層,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • spring中的@Value讀取配置文件的細節(jié)處理過程

    spring中的@Value讀取配置文件的細節(jié)處理過程

    這篇文章主要介紹了spring中的@Value讀取配置文件的細節(jié)處理過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Java跳過證書訪問HTTPS詳細代碼示例

    Java跳過證書訪問HTTPS詳細代碼示例

    在訪問HTTPS網(wǎng)站時,Java會默認檢查SSL證書是否有效,如果證書無效,則會阻止訪問,這篇文章主要給大家介紹了關(guān)于Java跳過證書訪問HTTPS的相關(guān)資料,需要的朋友可以參考下
    2024-02-02
  • 詳解spring注解配置啟動過程

    詳解spring注解配置啟動過程

    這篇文章主要為大家詳細介紹了詳解spring注解配置啟動過程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Java Scala數(shù)據(jù)類型與變量常量及類和對象超詳細講解

    Java Scala數(shù)據(jù)類型與變量常量及類和對象超詳細講解

    本文內(nèi)容主要分為3節(jié),依次講解:Scala的數(shù)據(jù)類型有哪些? 變量常量如何使用? 類和對象如何理解? 受限于博主的大腦容量,大概是無法做到事無巨細的,不過其實也沒必要那么"細",抓住主要脈絡(luò),加上大量的練習,融會貫通只不過是時間的問題
    2022-12-12
  • SpringBoot一個請求的處理全過程分享

    SpringBoot一個請求的處理全過程分享

    本文詳細介紹了SpringBoot請求處理的全過程,包括過濾器鏈、攔截器鏈、路徑映射、參數(shù)綁定、Controller方法執(zhí)行、返回值處理、異常解析和視圖解析渲染等步驟,同時,文中還列舉了請求處理過程中常見的問題及解決方案
    2024-12-12
  • sql查詢返回值使用map封裝多個key和value實例

    sql查詢返回值使用map封裝多個key和value實例

    這篇文章主要介紹了sql查詢返回值使用map封裝多個key和value實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • JAVA時間戳-Calendar類使用(包括set,get,add方法)

    JAVA時間戳-Calendar類使用(包括set,get,add方法)

    這篇文章主要介紹了JAVA時間戳-Calendar類使用(包括set,get,add方法),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • 淺析JAVA Lock鎖原理

    淺析JAVA Lock鎖原理

    這篇文章主要介紹了JAVA Lock鎖原理的相關(guān)資料,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07
  • Java 8 lambda表達式引入詳解及實例

    Java 8 lambda表達式引入詳解及實例

    這篇文章主要介紹了Java 8 lambda表達式引入詳解及實例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05

最新評論

涟源市| 鹤岗市| 玛沁县| 漾濞| 罗田县| 桦甸市| 边坝县| 南皮县| 田阳县| 双峰县| 南部县| 泽库县| 桦甸市| 杭州市| 郴州市| 阳春市| 万宁市| 桐梓县| 尉氏县| 乌海市| 谢通门县| 教育| 吴旗县| 鄂州市| 保亭| 宁化县| 陈巴尔虎旗| 鹿邑县| 通榆县| 九龙县| 门头沟区| 南乐县| 临沧市| 耿马| 当涂县| 花垣县| 兴义市| 渝中区| 舟曲县| 高阳县| 宜良县|