日期:2014-05-20  浏览次数:20886 次

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错误。