類的命名空間

在這裏插入圖片描述

前言

每一個類加載器都有各自的命名空間,命名空間是由該加載器及其所有父加載器所構成的,因此在每個類加載器中同一個class都是獨一無二的。

public class NameSpace {

    public static void main(String[] args) throws ClassNotFoundException {
        ClassLoader classLoader = NameSpace.class.getClassLoader();
        Class<?> aClass = classLoader.loadClass("fast.cloud.nacos.juc.classloader.HelloWorld");
        Class<?> bClass = classLoader.loadClass("fast.cloud.nacos.juc.classloader.HelloWorld");
        System.out.println(aClass.hashCode());
        System.out.println(bClass.hashCode());
        System.out.println(aClass == bClass);
    }
}

不論load多少次,你都將會發現他們始終是同一份class對象。但是使用不同類加載器,或者同一個類加載器的不同實例,去加載同一個class,則會在堆內存和方法區會產生多個class對象。

不同類加載器加載同一個class

public class DiffClassLoader {

    public static void main(String[] args) throws ClassNotFoundException {
        MyClassloader myClassloader = new MyClassloader();
        BrokerDelegateClassLoader brokerDelegateClassLoader = new BrokerDelegateClassLoader();
        Class<?> clazzA = myClassloader.loadClass("fast.cloud.nacos.juc.classloader.HelloWorld");
        Class<?> clazzB = brokerDelegateClassLoader.loadClass("fast.cloud.nacos.juc.classloader.HelloWorld");
        System.out.println(clazzA.getClassLoader());
        System.out.println(clazzB.getClassLoader());
        System.out.println(clazzA.hashCode());
        System.out.println(clazzB.hashCode());
        System.out.println(clazzA == clazzB);

    }
}

在這裏插入圖片描述

會生成兩個class實例。

相同類加載器加載同一個class


public class DoubleClassLoader {

    public static void main(String[] args) throws ClassNotFoundException {
        BrokerDelegateClassLoader myClassloaderA = new BrokerDelegateClassLoader();
        BrokerDelegateClassLoader myClassloaderB = new BrokerDelegateClassLoader();
        Class<?> clazzA = myClassloaderA.loadClass("fast.cloud.nacos.juc.classloader.HelloWorld");
        Class<?> clazzB = myClassloaderB.loadClass("fast.cloud.nacos.juc.classloader.HelloWorld");
        System.out.println(clazzA.getClassLoader());
        System.out.println(clazzB.getClassLoader());
        System.out.println(clazzA.hashCode());
        System.out.println(clazzB.hashCode());
        System.out.println(clazzA == clazzB);
    }

}

在這裏插入圖片描述
會生成兩個class實例。首先通過加載記錄表中的也就是緩存中的,查看該類是否已經被加載過了,如果加載過了,就不會重複加載了,否則將會認爲其實首次加載,也就是說同一個class實例在同一個類加載器命名空間之下是唯一的。

類的卸載

類的卸載需要滿足下面三個條件纔會被GC回收,也就是類被卸載。

  • 該類所有的實例都已經被GC
  • 加載該類的ClassLoader實例被回收
  • 該類的class實例沒有在其他地方被引用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章