JVM类加载机制---类加载器

一、概念
  “通过一个类的全限定名来获取描述此类的二进制字节流”,实现这个动作的代码模块成为 类加载器。

二、分类
  从java开发人员的角度出发,系统提供的类加载器大致分为如下3类:
  1、启动类加载器(Bootstrap ClassLoader)
    负责将存放在<JAVA_HOME>/lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别的类库加载到虚拟机内存中;
  2、扩展类加载器(Extension ClassLoader)
    负责加载<JAVA_HOME>/lib/ext目录中的,或者被java.ext.dirs系统变量指定的路径中的类库,开发者可以直接使用;
    3、应用程序类加载器(Application ClassLoader)
    负责加载用户类路径(ClassPath)上所指定的类库,开发者可以直接使用

  4、双亲委派模型

    


  1)定义:除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器,且加载器之间的父子关系一般不会继承,而是使用组合关系来复用父加载器的代码。

  2)工作过程:
  如果一个类加载器收到了类加载的请求,他首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父类加载器反馈自己无法完成这个加载请求(搜索范围内找不到所需的类)时,子加载器才会尝试自己去加载。

  3)实现:

protected synchronized Class<?> loadClass(String name,boolean resolve) {
    //首先查看请求类是否已被加载过
    Class c = findLoadedClass(name);
    if(c == null){
        try{
           if(parent != null){
               c = parent.loadClass(name,false);
           } else{
               c = findBootstrapClassOrNull(name);
           }
        }catch (ClassNotFoundException e){
            //父类加载器无法完成加载请求
        }
        //父类无法加载时在调用本身的findClass来进行类加载
        if(c == null){
            c = findClass(name);
        }
    }
    if(resolve){
        resolveClas();
    }
    return c;
}

  步骤解析:

  先检查是否已经被加载过,若没有则调用父加载器的loadClass()方法,若父加载器为空则默认是使用启动类加载器作为父加载器,若父类加载失败,抛出ClassNotFoundException后,再调用自己的findClass()方法进行加载。

原文地址:https://www.cnblogs.com/hunterCecil/p/6381808.html