类加载器的双亲委派模型_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 类加载器的双亲委派模型

类加载器的双亲委派模型

 2016/10/2 5:33:15  飞翔神话  程序员俱乐部  我要评论(0)
  • 摘要:双亲委派模型从Java虚拟机的角度来讲,只存在两种不同的类加载器:一种是启动类加载器(BootstrapClassLoader),这个类加载器使用C++实现,时虚拟器自身的一部分;另一种就是所有其他的类加载器,这类加载器都由Java实现,独立于虚拟机外部,并且都继承自抽象类java.lang.ClassLoader。从开发人员的角度来看,类加载器还可以划分的更细致一些,绝大部分Java程序都会使用到一下3中系统提供的类加载器。启动类加载器(BootstrapClassLoader)
  • 标签:

双亲委派模型
    从Java虚拟机的角度来讲,只存在两种不同的类加载器:一种是启动类加载器(Bootstrap ClassLoader),这个类加载器使用C++实现,时虚拟器自身的一部分;另一种就是所有其他的类加载器,这类加载器都由Java实现,独立于虚拟机外部,并且都继承自抽象类java.lang.ClassLoader。
    从开发人员的角度来看,类加载器还可以划分的更细致一些,绝大部分Java程序都会使用到一下3中系统提供的类加载器。
  • 启动类加载器(Bootstrap ClassLoader),这个类加载器前面已经介绍过,主要负责将存放在<JAVA_HOME>\lib目录中的,或者被-Xbootclasspath参数所指定的路径中的jar,并且是能够被虚拟机识别的(按照文件名识别,比如rt.jar,名字不符合虚拟机识别要求的即使放在该lib目录下也不会被加载)类库加载到虚拟机内存中。启动类加载器无法被Java程序直接引用,用户在编写自定义类加载器时,如果需要把加载请求委派给引导类加载器,那直接使用null代替即可。
  •    
  • 扩展类加载器(Extension ClassLoader):这个加载器由sun.misc.Launcher$ExtClassLoader实现,他负责加载<JAVA_HOME>/ext目录中的,或者被java.ext.dirs系统变量所指定的路径中的所有类库,开发者可以直接使用扩展类加载器。
  •    
  • 应用程序类加载器(Application ClassLoader):这个类加载器由sun.misc.Launcher$AppClassLoader实现。由于这个类加载器是ClassLoader中的getSystemClassLoader()方法的返回值,所以一般也称它为系统类加载器。他负责加载用户类路径(ClassPath)上所指定的类库,开发者可以直接使用这个类加载器器,如果应用程序中没有自定义过自己的类加载器,那么一般情况这个就是程序中默认的类加载器。
    我们的应用程序都是由这3中类加载器互相配合进行加载的,如果有必要,还可以加入我们自定义的类加载器,这些类加载器的关系如下图所示:

    上图中所展示的类加载器之间的层次关系,成为类加载器的双亲委派模型(Parents Delegation Model)。双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器。但是这里类加载器之间的父子关系一般不会以继承的关系来实现,而是都是使用组合的方式来复用父类加载器的代码。
     类加载器的双亲委派模型在JDK1.2期间被引入并广泛应用于几乎所有的Java程序中,但它并不是一个强制性的约束模型,而是Java设计者推荐给开发者的一种类加载器实现方式。
     工作过程:如果一个类加载器收到了类加载的请求,他首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。
      使用双亲委派模型的好处:Java类随着它的类加载器一起具备了一种带有优先级的层次关系。它存放在rt.jar中,无论哪一个类加载器都要加载这个类,最终都是委派给处于最顶端的启动类加载器进行加载,因此Object类在程序中的各种类加载环境中都是同一个类,相反,如果没有使用双亲委派模型,由各个类加载器自行去加载的话,(如果用户自己编写了一个不同的java.lang.1Object类,并放在classpath中,那么系统中将会出现多个不同的Object类,这样一来Java类型体系中最基础的行为也就无法保证,应用程序也将变得一片混乱),那么会使整个工程变得混乱。

      双亲委派模型对于保证Java程序的稳定运行很重要,但是它的实现却非常简单,实现双亲委派模型的代码都集中在java.lang.ClassLoader的loadClass()方法中。

     注意:即使是自定义了自己的类加载器,强行用defineClass()方法去加载一个以"java.lang"开头的类也不会成功。如果你尝试这么做,那么将会受到一个有虚拟机抛出的"java.lang.SecurityException:prohibited package name:java.lang"异常
   
参考资料:
《深入理解Java虚拟机:JVM高级特性与最佳实践》 周志明著
http://www.360doc.com/content/14/0803/16/8072791_399149454.shtml
  • 大小: 49.5 KB
  • 查看图片附件
  • 相关文章
发表评论
用户名: 匿名