zoukankan      html  css  js  c++  java
  • java classloader

      一个jvm中默认的classloader有Bootstrap ClassLoader、Extension   ClassLoader、App ClassLoader,分别各司其职:

    •           Bootstrap       ClassLoader     负责加载java基础类,主要是       %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等
         
    •           Extension ClassLoader            负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class
         
    •           App ClassLoader           负责加载当前java应用的classpath中的所有类。
    classloader 加载类用的是全盘负责委托机制。 所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入。  
    所以,当我们自定义的classlo ader加载成功了 com.company.MyClass以后,MyClass里所有依赖的class都由这个classLoader来加载完成。
     
    ClassLoader使用的是   双亲委托模型 来搜索类的,每个ClassLoader实例都有一个父类加载器的引用(不是 继承的关系,是一个包含的关系),虚拟机内置的类加载器(Bootstrap   ClassLoader)本身没有父类加载器,但可以用作其它ClassLoader实例的的父类加载器。
    当一个ClassLoader实例需要加载某个 类时,它会试图亲自搜索某个类之前,先把这个任务委托给它的父类加载器,这个过程是由上至下依次检查的,首先由最顶层的类加载器Bootstrap   ClassLoader试图加载,如果没加载到,则把任务转交给Extension   ClassLoader试图加载,如果也没加载到,则转交给App ClassLoader 进行加载,如果它也没有加载得到的话,则返回给委托的发起者,由它到指定的文件系统或网络等URL中加载该类。如果它们都没有加载到这个类时,则抛出 ClassNotFoundException异常。否则将这个找到的类生成一个类的定义,并将它加载到内存当中,最后返回这个类在内存中的Class实例对象。
     
     
    比较两个类是否相等,只有这两个类是由同一个类加载器加载才有意义。否则,即使这两个类是来源于同一个Class文件,只要加载它们的类加载器不同,那么这两个类必定不相等。
    补充:

              1.               什么是类加载器?    

        把类加载的过程放到Java虚拟机外部去实现,让应用程序决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。      

              2.               有哪些类加载器,分别加载哪些类    

        类加载器按照层次,从顶层到底层,分为以下三种:         (1)启动类加载器 : 它用来加载 Java 的核心库,比如String、System这些类         (2)扩展类加载器 : 它用来加载 Java 的扩展库。

        (3)     应用程序类加载器 : 负责加载用户类路径上所指定的类库,一般来说,Java 应用的类都是由它来完成加载的。

              3.               双亲委派模型    

        我们应用程序都是由以上三种类加载器互相配合进行加载的,还可以加入自己定义的类加载器。称为           类加载器的双亲委派模型         ,这里类加载器之间的父子关系一般不会以继承的关系来实现,而是都使用           组合关系         来复用父加载器的。

              4.               双亲委托模型的工作原理    

        是当一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载 都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法加载这个加载请求的时候,子加载器才会尝试自己去加载。

              5.               使用双亲委派模型好处?(原因)    

        第一:可以避免重复加载,当父亲已经加载了该类的时候,子类不需要再次加载。

        第二:考虑到安全因素,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义类型,这样会存在非常大的安全隐患,而双亲委托的方式,就可以避免这种情况,因为String已经在启动时被加载,所以用户自定义类是无法加载一个自定义的类装载器。

     

     

  • 相关阅读:
    032 Gradle 下载的依赖jar包在哪?
    031 can't rename root module,Android Studio修改项目名称
    030 Cannot resolve symbol'R' 问题解决汇总大全
    029 Android Studio层级显示目录文件
    028 You are about to commit CRLF line separators to the Git repository.It is recommended to set the core. autocrlf Git attribute to true to avoid line separator issues If you choose Fix and Comit ,
    027 【Android基础知识】Android Studio 编译慢及 Adb connection Error:远程主机强迫关闭了一个现有的连接
    026 Android Studio 和Gradle版版本对应关系
    025 Cause: org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierIm
    024 Android Studio上传项目到Github 最全记录
    023 解决AndroidStudio下载gradle慢的问题
  • 原文地址:https://www.cnblogs.com/Berryxiong/p/6194995.html
Copyright © 2011-2022 走看看