知识大全 ClassLoader介绍

Posted 机制

篇首语:有了坚定的意志,就等于给双脚添了一对翅膀。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 ClassLoader介绍相关的知识,希望对你有一定的参考价值。

ClassLoader介绍  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  JVM在运行时会产生三个ClassLoader Bootstrap ClassLoader Extension ClassLoader和AppClassLoader 其中 Bootstrap是用C++编写的 我们在Java中看不到它 是null 它用来加载核心类库 在JVM源代码中这样写道   static const char classpathFormat[] =   %/lib/rt jar:    %/lib/i n jar:    %/lib/sunrsasign jar:    %/lib/jsse jar:    %/lib/jce jar:    %/lib/charsets jar:    %/classes ;  知道为什么不需要在classpath中加载这些类了吧?人家在JVM启动的时候就自动加载了 并且在运行过程中根本不能修改Bootstrap加载路径   Extension ClassLoader用来加载扩展类 即/lib/ext中的类   最后AppClassLoader才是加载Classpath的   ClassLoader加载类用的是委托模型 即先让Parent类(而不是Super 不是继承关系)寻找 Parent找不到才自己找 看来ClassLoader还是蛮孝顺的 三者的关系为:AppClassLoader的Parent是ExtClassLoader 而ExtClassLoader的Parent为Bootstrap ClassLoader 加载一个类时 首先BootStrap先进行寻找 找不到再由ExtClassLoader寻找 最后才是AppClassLoader   为什么要设计的这么复杂呢?其中一个重要原因就是安全性 比如在Applet中 如果编写了一个java lang String类并具有破坏性 假如不采用这种委托机制 就会将这个具有破坏性的String加载到了用户机器上 导致破坏用户安全 但采用这种委托机制则不会出现这种情况 因为要加载java lang String类时 系统最终会由Bootstrap进行加载 这个具有破坏性的String永远没有机会加载   我们来看这段代码   [code]//A java  public class A  public static void main(String[] args)  A a=new A();  System out println(System getProperty( java ext dirs ));  System out println(a getClass() getClassLoader());  B b=new B();  b print();      //B java  public class B  public void print()  System out println(this getClass() getClassLoader());    [/code]     我们将它放在Classpath中 则打印出  sun misc Launcher$AppClassLoader@ e c  sun misc Launcher$AppClassLoader@ e c  可见都是由AppClassLoader来加载的    我们将其放在%jre%/lib/ext/classes(即ExtClassLoader的加载目录 其加载/lib/ext中的jar文件或者子目录classes中的class文件)中 则会打印出   sun misc Launcher$ExtClassLoader  sun misc Launcher$ExtClassLoader   我们将A class放到%jre%/lib/ext/classes中 而将B class放到classpaht中又会怎么样呢?结果是   sun misc Launcher$ExtClassLoader  Exception in thread main java lang NoClassDefFoundError:B  at A main(A java: )    怎么会这样呢?这其中有一个重要的问题 A类当然是由ExtClassLoader来加载的 B类要由哪个加载呢?B类要由调用它自己的类的类加载器(真拗口) 也就是说 A调用了B 所以B由A的类加载器ExtClassLoader来加载 ExtClassLoader根据委托机制 先拜托Bootstrap加载 Bootstrap没有找到 然后它再自己寻找B类 还是没找到 所以抛出异常 ExtClassLoader不会请求AppClassLoader来加载!你可能会想 这算什么问题 我把两个类放到一起不就行了?    呵呵 没这么简单 比如JDBC是核心类库 而各个数据库的JDBC驱动则是扩展类库或在classpath中定义的 所以JDBC由Bootstrap ClassLoader加载 而驱动要由AppClassLoader加载 等等 问题来了 Bootstrap不会请求AppClassLoader加载类啊 那么 他们怎么实现的呢?我就涉及到一个Context ClassLoader的问题 调用Thread getContextClassLoader cha138/Article/program/Java/JSP/201311/19529

相关参考