zoukankan      html  css  js  c++  java
  • 如何理解java的类加载器ClassLoader

          看了很多java的基础教程,对类加载器的理解都比较模糊。总结了几位博主的分析,由此对类加载器有了深入一点的认识。

          以下部分来自百度文库:

          与普通程序不同的是,Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。
    JVM本身包含了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,BootstrapClassLoader是用本地代码实现的,它负责加载核心JavaClass(即所有java.*开头的类)。另外JVM还会提供两个ClassLoader,它们都是用Java语言编写的,由BootstrapClassLoader加载;其中Extension ClassLoader负责加载扩展的Javaclass(例如所有javax.*开头的类和存放在JRE的ext目录下的类),ApplicationClassLoader负责加载应用程序自身的类。
          当运行一个程序的时候,JVM启动,运行bootstrapclassloader,该ClassLoader加载java核心API(ExtClassLoader和AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一个程序最基本的加载流程。

          当决定创建你自己的ClassLoader时,需要继承java.lang.ClassLoader或者它的子类。在实例化每个ClassLoader对象时,需要指定一个父对象;如果没有指定的话,系统自动指定ClassLoader.getSystemClassLoader()为父对象。所以当创建自己的Class Loader时,只需要重载findClass()这个方法。

          以下部分转自http://blog.csdn.net/wxwzy738/article/details/8532123

          类加载器之间的父子关系(注:并非真正的继承,只是定义上的,不是针对类而是针对对象来说,即孩子有一个指向父亲的引用):

       

          一般类加载器的加载过程如下:
     
          调用 findLoadedClass() 来查看是否存在已装入的类。
          如果没有,那么获取class文件的原始字节。(通过IO从文件系统,来自网络的字节流等)
          如果已有原始字节,调用 defineClass() 将它们转换成 Class 对象。
          如果没有原始字节,然后调用 findSystemClass() 查看是否从本地文件系统获取类
          如果 resolve 参数是 true,那么调用 resolveClass() 解析 Class 对象。
          如果还没有类,返回 ClassNotFoundException。
          否则,将类返回给调用程序。
     
          类加载器的委托机制:
      
          当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
          首先当前线程的类加载器去加载线程中的第一个类。
          如果类A中引用了类B,Java虚拟机将使用加载类A的类装载器来加载类B。
          还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。
          每个类加载器加载类时,又先委托给其上级类加载器。
          当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛ClassNotFoundException,不是再去找发起者类加载器的儿子,因为没有getChild方法,即使有,那有多个儿子,找哪一个呢?
          对着类加载器的层次结构图和委托加载原理,解释先前将ClassLoaderTest输出成jre/lib/ext目录下的itcast.jar包中后,运行结果为ExtClassLoader的原因。

          每个ClassLoader本身只能分别加载特定位置和目录中的类,但它们可以委托其他的类装载器去加载类,这就是类加载器的委托模式。类装载 器一级级委托到BootStrap类加载器,当BootStrap无法加载当前所要加载的类时,然后才一级级回退到子孙类装载器去进行真正的加载。当回退到最初的类装载器时,如果它自己也不能完成类的装载,那就应报告ClassNotFoundException异常。
     
          以下部分来自bbs.itheima.com/thread-51369-1-1.html
     
          简单的说:加载某个类时,优先使用父类加载器加载需要使用的类。如果我们自定义了java.lang.String这个类,加载该自定义的String类,该自定义String类使用的加载器是AppClassLoader,根据优先使用父类加载器原理,AppClassLoader加载器的父类为ExtClassLoader,所以这时加载String使用的类加载器是ExtClassLoader但是类加载器ExtClassLoaderjre/lib/ext目录下没有找到String.class类。然后使用ExtClassLoader父类的加载器BootStrap父类加载器BootStrapJRE/lib目录的rt.jar找到了String.class,将其加载到内存中。这就是类加载器的委托机制。
  • 相关阅读:
    跨域
    redis安装
    iframe操作
    element-ui 合并相邻的相同行 span-method
    函数实现 a?.b?.c?.d
    git 使用流程 命令
    svg用作背景图
    js中的位运算符 ,按位操作符
    二十三种设计模式[23]
    二十三种设计模式[22]
  • 原文地址:https://www.cnblogs.com/4114s/p/5264545.html
Copyright © 2011-2022 走看看