1. 程式人生 > >jvm原理(17)類載入器名稱空間深度解析與例項分析

jvm原理(17)類載入器名稱空間深度解析與例項分析

我們在 上一節講到例項基礎上做一下改動:

public class MyTest21 {
    public static void main(String[] args)  throws Exception{
        MyTest16 loader1 = new MyTest16("loader1") ;
        MyTest16 loader2 = new MyTest16("loader2") ;
        loader1.setPath("E:\\data\\classes\\");
        loader2.setPath("E:\\data\\classes\\"
); Class<?> clazz1 = loader1.loadClass("com.twodragonlake.jvm.classloader.MyPerson"); Class<?> clazz2 = loader2.loadClass("com.twodragonlake.jvm.classloader.MyPerson"); System.out.println(clazz1 == clazz2); Object object1 = clazz1.newInstance(); Object object2 = clazz2.newInstance(); Method method = clazz1.getMethod("setMyPerson"
,Object.class); method.invoke(object1,object2); } }

即指定了loader1和loader2的path路徑,然後我們重新編譯當前工程,將com.twodragonlake.jvm.classloader.MyPerson的class檔案複製一份到【E:\data\classes\】下邊,然後刪除當前工程的MyPerson的class檔案,然後執行MyTest21 的main函式,列印 結果會是什麼呢?

findClass invoked com.twodragonlake.jvm.classloader.MyPerson
this.classLoaderName : loader1 findClass invoked com.twodragonlake.jvm.classloader.MyPerson this.classLoaderName : loader2 false Exception in thread "main" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.twodragonlake.jvm.classloader.MyTest21.main(MyTest21.java:18) Caused by: java.lang.ClassCastException: com.twodragonlake.jvm.classloader.MyPerson cannot be cast to com.twodragonlake.jvm.classloader.MyPerson at com.twodragonlake.jvm.classloader.MyPerson.setMyPerson(MyPerson.java:6) ... 5 more

分析:首先loader1和loader2雖然都是MyTest16的物件,但是他們之間在類載入的層次上沒有任何的關係,loader1載入MyPerson的時候通過向上委託一直到啟動類載入器然後又往下到應用類載入器都無法載入,只能通過loader1載入器來載入,loader1載入的MyPerson的class物件clazz1屬於loader1的名稱空間,同樣的道理clazz2屬於loader2的名稱空間,clazz1和clazz2是不同的2個class物件,所以我們在通過反射呼叫clazz1的實體object1的setMyPerson方法的時候,傳入的是clazz2的實體物件,clazz2和clazz1屬於不同的名稱空間,相互之間不可見,在強制向下轉型的時候肯定是丟擲轉型失敗的錯誤。
這裡寫圖片描述
這裡寫圖片描述
子載入器載入的類可以看到父載入器載入的類;
父載入器載入的類無法看到子載入器載入的類;