Class Loading作为java程序执行的第一步,虚拟机对这部分并没有严格的说明,因此这个阶段对于程序员而言就有着非常大的灵活性,这点对于java的技术的发展也有非常大的作用,比如说动态代理,OSGI,JSP等。

从JVM的角度出发类加载器主要分两类

一:启动类加载器

         主要负责把<JAVA_HOME>/jre/lib目录下(或者是-Xbootclasspath指定的路径)的能被虚拟机识别的jar加载到虚拟机内存中。

          不可扩展,不可以被程序员引用

二:除了第一种的所有加载器

        这些加载器都继承自java.lang.ClassLoader类

从用户的角度看的话除了启动类加载器外还可以分为

一:扩展类加载器

       这个加载器由sun.misc.Launcher$ExtClassLoader实现,主要负责加载<JAVA_HOME>/jre/lib/ext目录下的jar到内存中,还可以加载系统变量java.ext.dirs定义目录下的jar包

        开发者可以直接使用这个加载器

二:应用程序加载器

        这个加载器由sun.misc.Launcher$AppClassLoader来实现,主要负责加CLASSPATH定义的jar,开发者也可以直接使用这个加载器,如果没有定义自己的类加载器,那么它将是系统的默认加载器

 

前面描述了类加载器的大致分类以及特点,接下来说明一下什么叫Parents Delegation Model,以及这种模型有什么优点以及为什么要弄这个模型?

(1)什么叫Parents Delegation Model?

所谓的Parents Delegation Model其实就是一种类加载器之间的层次关系,具体的说就是它规定最顶层的类加载器必须为启动类加载器,其余的类加载器必须有自己的父类加载器,且上下层关系的加载器一般是用组合而不是继承来实现的,下图为大概的层次机构关系

 

(2)这种模型的作用何在?

在说作用之前首先讲一下这种模型的工作原理,其原理可以用一句话概括:尽量让父类加载器去加载请求加载的类.只有当父类加载器加载不到对应的类时,才会用子类加载器去加载

例如当要加载java.lang.Object的时候,由于这种模型会尽量让父类加载器去加载,由于java.lang.Object 属于<JAVA_HOME>/jre/lib/rt.jar,所以当用启动类加载器去加载的时候,可以加载到需要的类,又由于类的唯一性是由加载器+类本生 来确定的,所以双亲委派模型保证了java程序的稳定运行.

 

要注意的是虽然这种模型对于java程序的稳定运行起到了很重要的作用,但是它并不是虚拟机规范强制要求的

 

 

 

 

 

 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐