chapter07_虚拟机类加载机制_4_类加载器

  • 类加载器

    (1) 作用:通过一个类的全限定名获取类的二进制字节流

    (2) 类的唯一性由__类加载器__和__类__本身 一起保证

    即便采用了单例模式,如果类加载器不同,加载出的两个类的对象也不同

  • 类加载器的分类

    (1) 分类一

    启动类加载器

    用C++编写,是JVM的一部分,负责将/lib中的类库加载到虚拟机内存中,无法被Java程序直接引用

    2° 其他类加载器

    用java编写

    (2) 分类二

    启动类加载器

    同 (1) 1°

    扩展类加载器

    负责加载/lib/ext中的类库,开发者可以直接使用

    应用程序类加载器

    是ClassLoader类的静态方法getSystemClassLoader()的返回值,负责加载__用户类路径(classpath)__上的类库。

    如果开发者没有自定义类加载器,这个就是默认的类加载器

    自定义类加载器

    自己编写的ClassLoader的实现类

  • 双亲委派模型

    (1) 类加载器的层次结构

             启动类加载器
                  ^
                  |
                  |
             扩展类加载器
                  ^
                  |
                  |
            应用程序类加载器
                ^        ^
                |        |
                |        |
      自定义类加载器1  自定义类加载器2  ...
    

    (2) 工作过程

    1° 任何一个类加载器收到了类加载的请求,它都先__委托给自己的上层__父加载器加载(这是个递归调用的过程),直到最上层的启动类加载器

    2° 如果上层的加载器成功加载,那就结束;如果上层加载器加载失败,再由自己加载

    (3) 好处

    防止同一个底层类被不同类加载器加载的情况

    例如现在有两个自定义类加载器,它们每个都要加载Object类。如果不采用双亲委派模型,都是自己就加载,那Object类会出现两套;现在的情况是它们都逐级向上最终交给启动类加载器去加载,这样只出现了一套Object类

    (4) 双亲委派模型的实现很简单,就是照着上面的思路,在ClassLoader类有实现

      ClassLoader.java
    
      protected Class<?> loadClass(String name, boolean resolve)
      throws ClassNotFoundException {
    
          synchronized (getClassLoadingLock(name)) {
    
              // First, check if the class has already been loaded
              Class<?> c = findLoadedClass(name);
          
              if (c == null) {
    
                  long t0 = System.nanoTime();
                  try {
                      if (parent != null) {
                          c = parent.loadClass(name, false);
                      } else {
                          c = findBootstrapClassOrNull(name);
                      }
                  } catch (ClassNotFoundException e) {
                      // ClassNotFoundException thrown if class not found
                      // from the non-null parent class loader
                  }
    
                  if (c == null) {
                      // If still not found, then invoke findClass in order
                      // to find the class.
                      long t1 = System.nanoTime();
                      c = findClass(name);
    
                      // this is the defining class loader; record the stats
                      PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                      PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                      PerfCounter.getFindClasses().increment();
                  }
              }
    
              if (resolve) {
                  resolveClass(c);
              }
              return c;
          }
      }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值