类加载器命名空间深度解析与实例分析
不同类加载器的命名空间关系:
- 同一个命名空间内的类是相互可见的。
- 子加载器的命名空间包含所有父类加载器的命名空间。因此由子加载器加载的类能看见父加载器加载的类。例如系统类加载器加载的类能看见根类加载器加载的类。
- 由父加载器加载的类不能看见子加载器加载的类。
- 如果两个加载器之间没有直接或者间接的父子关系,那么它们各自加载的类相互不可见。
实例一:
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、loader2去加载MyPerson的时候,都是由双亲委托机制,请求其父类加载器去加载,第一次loader1请求父类加载器(系统类加载器)完成加载;当第二次loader2加载的时候,请求父类加载器(系统类加载器)去加载,发现MyPerson已经被加载,就不再重新加载了,直接返回加载结果即可。
实例二:
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
- 为false的原因:**如果两个加载器之间没有直接或者间接的父子关系,那么它们各自加载的类相互不可见。**所以loader1和loader2是两个不同类加载器(不同类加载器有着不同的命名空间,但是,在这两个不同的命名空间中有着相同的类MyPerson)。