名前空間のクラスローダの詳細な分析とケーススタディ
名前空間の関係異なるクラスローダ:
- 同じ名前空間のクラスは、相互に表示されます。
- 名前空間の子ローダー名前空間は、親クラスローダのすべてが含まれています。このように、サブロードされたクラスローダがロードすることによりにより、あなたは親クラスを見ることができます。たとえば、クラスをロードするためのシステムクラスローダは、クラスをロードするには、ルートクラスローダを見ることができます。
- 親子クラスローダの負荷を見ることができないクラスローダによってロードされます。
- 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 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:
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を有している)です。