类加载器的委托机制

类加载器的委托机制

当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?

首先当前线程的类加载器去加载线程中的第一个类。

如果类A中引用了类B,Java虚拟机将使用加载类A的类装载器来加载类B。

还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。

每个类加载器加载类时,又先委托给其上级类加载器。

当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛ClassNotFoundException,不是再去找发起者类加载器的儿子,,因为没有getChild方法,即使有,那有多个儿子,找哪一个呢?

对着类加载器的层次结构图和委托加载原理,解释先前将ClassLoaderTest输出成jre/lib/ext目录下的itcast.jar包中后,运行结果为ExtClassLoader的原因。

每个ClassLoader本身只能分别加载特定位置和目录中的类,但它们可以委托其他的类装载器去加载类,这就是类加载器的委托模式。类装载器一级级委托到BootStrap类加载器,当BootStrap无法加载当前所要加载的类时,然后才一级级回退到子孙类装载器去进行真正的加载。当回退到最初的类装载器时,如果它自己也不能完成类的装载,那就应报告ClassNotFoundException异常。

l有一道面试,能不能自己写个类叫java.lang.System,为了不让我们写System类,类加载采用委托机制,这样可以保证爸爸们优先,也就是总是使用爸爸们能找到的类,这样总是使用java系统提供的System。

把先前编写的类加入到jdk的rt.jar中,会有怎样的效果呢?不行!!!看来是不能随意将自己的class文件加入进rt.jar文件中的。

public class Test {public static void main(String[] args) {//加载器:sun.misc.Launcher$AppClassLoaderSystem.out.println(Test.class.getClassLoader().getClass().getName());//加载器:BootStrap(loader为null的情况)System.out.println(System.class.getClassLoader());//System.out.println("—————-查看类加载器的层次结构关系——————-");ClassLoader loader = Test.class.getClassLoader();while(loader != null){System.out.println(loader.getClass().getName());loader = loader.getParent();}System.out.println(loader);}/** * 运行结果: * sun.misc.Launcher$AppClassLoadernull—————-查看类加载器的层次结构关系——————-sun.misc.Launcher$AppClassLoadersun.misc.Launcher$ExtClassLoadernull */}

行动是治愈恐惧的良药,而犹豫、拖延将不断滋养恐惧。

类加载器的委托机制

相关文章:

你感兴趣的文章:

标签云: