Java面试问题之十四
请阐述一下不同类加载器加载的类之间的可见性。
答:不同类加载器的命名空间存在以下关系:
(1)同一命名空间内的类是相互可见的。
(2)子加载器的命名空间包含所有父加载器的命名空间。因此由子加载器加载的类能看见
其父加载器加载的类。比如,系统类加载器加载的类能够看见根类加载器加载的类。 (3)由父加载器加载的类不能看见子加载器加载的类。 (4)如果两个加载器之间没有直接或间接的父子关系,那么它们各自加载的类相互是不可
见的。
比如,我现在定义了一个加载器类MyClassLoader,这个类是继承自java.lang.ClassLoader类。MyClassLoader的一个对象为loader1,则下面代码会抛出
java.lang.NoClassDefFoundError。
public static void main(String[] args){
MyClassLoader loader1=new MyClassLoader("loader1");
loader1.setPath("D:\\Java\\Program\\Exercises");
Class objClass=loader1.loadClass("Sample");
Object obj=objClass.newInstance();
Sample sample=(Sample)obj; //这句将抛出NoClassDefFoundError错误!
System.out.println(sample.v1);
}
问题分析:由于MyClassLoader类是由系统类加载器加载的,而Sample类则是由loader1类加载的,因此MyClassLoader类是看不见Sample类的。因此,在MyClassLoader类的main()方法中使用Sample类,会导致NoClassDefFoundError错误。