22-名前空間のクラスローダの詳細な分析とケーススタディ

名前空間のクラスローダの詳細な分析とケーススタディ

名前空間の関係異なるクラスローダ:

  • 同じ名前空間のクラスは、相互に表示されます。
  • 名前空間の子ローダー名前空間は、親クラスローダのすべてが含まれています。このように、サブロードされたクラスローダがロードすることによりにより、あなたは親クラスを見ることができます。たとえば、クラスをロードするためのシステムクラスローダは、クラスをロードするには、ルートクラスローダを見ることができます。
  • 親子クラスローダの負荷を見ることができないクラスローダによってロードされます。
  • 2つのローダーとの間に直接または間接的な親子関係が存在しない場合は、各ロードされたクラスがお互いに見えないです。

例1:

public class MyPerson {
    private MyPerson myPerson;
    public void setMyPerson(Object object) {
        this.myPerson = (MyPerson)object;
    }
}

public class MyTest20 {
    public static void main(String[] args) throws Exception {
        //MyTest16是一个自定义类加载器
        MyTest16 loader1 = new MyTest16("loader1");
        MyTest16 loader2 = new MyTest16("loader2");

        Class<?> clazz1 = loader1.loadClass("Jvm.MyPerson");
        Class<?> clazz2 = loader2.loadClass("Jvm.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);
    }
}
运行结果:
	true
  • まず、結果は印刷:するSystem.out.println(clazz1 == clazz2);負荷に理由loader1、両親が初めてその親クラスローダを要求するためのメカニズムから委託されている負荷MyPersonにloader2ローディングを完了するloader1要求親クラスローダ(システムクラスローダ); loader2負荷への第2負荷、親クラスローダ要求(システムクラスローダが)MyPersonがロードされた見つかった場合、それはもはや再ロードされます、結果が戻って直接ロードすることができます。

例2:

//前提:删除out文件夹中的MyPerson.class,并将其复制到桌面上去。
public class MyTest21 {
    public static void main(String[] args) throws Exception {
        MyTest16 loader1 = new MyTest16("loader1");
        MyTest16 loader2 = new MyTest16("loader2");
        loader1.setPath("C:\\Users\\admin\\Desktop\\");
        loader2.setPath("C:\\Users\\admin\\Desktop\\");
        Class<?> clazz1 = loader1.loadClass("Jvm.MyPerson");
        Class<?> clazz2 = loader2.loadClass("Jvm.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);
    }
}
运行结果:
   findClass invoked:Jvm.MyPerson
   class loader name:loader1
   findClass invoked:Jvm.MyPerson
   class loader name:loader2
   -------------------
   false
   Exception in thread "main" java.lang.reflect.InvocationTargetException
   Caused by: java.lang.ClassCastException: Jvm.MyPerson cannot be cast to Jvm.MyPerson
  • 偽の理由:** 2つのローダーとの間に直接または間接的な親子関係が存在しない場合、彼らはそれぞれのロードされたクラスでは、お互いに見えません。**などloader1のloader2二つの異なるクラスローダ(異なるクラスローダーが異なる名前空間が、しかし、2つの異なる名前空間が同じクラスMyPersonを有している)です。
公開された25元の記事 ウォンの賞賛0 ビュー1451

おすすめ

転載: blog.csdn.net/qq_40574305/article/details/104793474
おすすめ