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,将其加载到内存中。这就是类加载器的委托机制。
  • 相关阅读:
    Asp.Net Web API 2第八课——Web API 2中的属性路由
    Asp.Net Web API 2第七课——Web API异常处理
    Asp.Net Web API 2第六课——Web API路由和动作选择
    Asp.Net Web API 2第五课——Web API路由
    开始学习python
    BMI 小程序 购物车
    深浅copy 文件操作
    字典 dict 集合set
    基本数据类型 (str,int,bool,tuple,)
    python 运算符
  • 原文地址:https://www.cnblogs.com/4114s/p/5264545.html
Copyright © 2011-2022 走看看