自己寫自己的java.lang.Object會怎麼樣?

首先自己定義一個包叫做java.lang,然後在裏面定義一個類叫做Object.
然後在裏面定義一個方法叫做toString(),返回null.另一個叫sayHello()

package java.lang;

public class Object {

    public String toString() {
        return null;
    }

    public void sayHello() {
        System.out.println("hello");
    }

}

然後在另一個包裏面使用Object對象:

package top.test;

import java.lang.Object;

public class ObjectTest {

    public static void main(String[] args) {
        Object o = new Object();
        System.out.println(o.toString());
        o.sayHello();
    }

}

猜一猜這個Object會是哪個Object呢?
有人猜是自己寫的哪個Object嗎?因爲o.sayHello()都調用成功了,Eclipse沒有報錯,那麼肯定是自己寫的哪個Object啊.但是當我們嘗試去運行時,出現問題了

會報java.lang.NoSuchMethodError異常,說沒有找到這個方法.

爲什麼?
這是因爲java的類加載機制是基於”雙親委派模型”,看下面這個圖:
這裏寫圖片描述
java的類加載器分爲4類,如圖所示,當加載一個類的時候,如果我們沒有定義自己的類加載器,默認是使用Application ClassLoader.除了Bootstrap ClassLoader以外,都有自己的父類加載器.
雙親委派模型的機制是這樣的(這個機制不是強制的,自己的類加載器可以不遵守):

如果接收到了一個類加載請求,總是嘗試着把這個請求傳送給父類加載器,只有在父類加載器不能處理這個請求的時候,自己才嘗試加載

實現這個邏輯需要在代碼中自行實現,不是強制的.

解釋我們程序的結果:
所以當我們加載自己寫的java.lang.Object時,會默認調用Appliation ClassLoader,這是系統提供的類加載器,肯定支持”雙親委派模型”,所以我們的請求會一步步提交到Bootstrap ClassLoader那裏,這個類默認加載的類位於$JAVA_HOME/jre/lib下面的rt.jar包,可以找到我們需要的java.lang.Object類,所以加載的自然就不是我們自己寫的Object類了.

經測試,在Eclipse寫出這樣的代碼不會報錯,但是在Idea中會報錯,看來還是Idea更強大一些.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章