类加载机制 - 日理万妓 2022-07-12 07:15 283阅读 0赞 # 类加载器层次是怎么样的 # 1. JVM预定义的三种类型类加载器: * 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 `<Java_Runtime_Home>/lib`下面的类库加载到内存中(比如`rt.jar`)。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。 * 标准扩展(Extension)类加载器:是由 Sun 的 `ExtClassLoader(sun.misc.Launcher$ExtClassLoader)`实现的。它负责将`< Java_Runtime_Home >/lib/ext`或者由系统变量 `java.ext.dir`指定位置中的类库加载到内存中。开发者可以直接使用标准扩展类加载器。 * 系统(System)类加载器:是由 Sun 的 `AppClassLoader(sun.misc.Launcher$AppClassLoader)`实现的。它负责将系统类路径(`CLASSPATH`)中指定的类库加载到内存中。开发者可以直接使用系统类加载器。 除了以上列举的三种类加载器,还有一种比较特殊的类型 — 线程上下文类加载器。 # 双亲委派模型是什么?有什么好处? # 某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。 委托机制的意义 — 防止内存中出现多份同样的字节码 比如两个类A和类B都要加载System类: * 如果不用委托而是自己加载自己的,那么类A就会加载一份System字节码,然后类B又会加载一份System字节码,这样内存中就出现了两份System字节码。 * 如果使用委托机制,会递归的向父类查找,也就是首选用Bootstrap尝试加载,如果找不到再向下。这里的System就能在Bootstrap中找到然后加载,如果此时类B也要加载System,也从Bootstrap开始,此时Bootstrap发现已经加载过了System那么直接返回内存中的System即可而不需要重新加载,这样内存中就只有一份System的字节码了。 # 当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢? # * 首先当前线程的类加载器去加载线程中的第一个类(假设为类A)。 注:当前线程的类加载器可以通过Thread类的getContextClassLoader()获得,也可以通过setContextClassLoader()自己设置类加载器。 * 如果类A中引用了类B,Java虚拟机将使用加载类A的类加载器去加载类B。 * 还可以直接调用`ClassLoader.loadClass()`方法来指定某个类加载器去加载某个类。 # 如果定义自己的符合双亲委派模型的加载器类? # 继承java.lang.ClassLoader,并重新findClass方法,以指定如何找到并加载class字节流,最早的自定义加载器是通过重载loadClass实现的,为了符合双亲委派模型,一般不建议再重写此方法。 # 获取加载器的方法总结 # **获得系统类加载器** ![复制代码][copycode.gif] public class testClassLoader { @Test public void test(){ //application class loader System.out.println(ClassLoader.getSystemClassLoader()); //extensions class loader System.out.println(ClassLoader.getSystemClassLoader().getParent()); //bootstrap class loader System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent()); } } ![复制代码][copycode.gif] 输出为: ![132044146448948.png][] 可以看出ClassLoader类是由AppClassLoader加载的。他的父亲是ExtClassLoader,ExtClassLoader的父亲无法获取是因为它是用C++实现的。 ## 获得指定类的加载器 Lotto.class.getClassLoader(); ## # 加载器常用方法总结 # <table style="border-collapse:collapse; border-spacing:0px; max-width:100%; width:847px; margin-bottom:20px; color:rgb(51,51,51); font-family:"Helvetica Neue",Helvetica,Arial,sans-serif; font-size:14px"> <thead style=""> <tr style=""> <th style="padding:8px; text-align:left; line-height:1.42857; vertical-align:bottom; border-top:0px; border-bottom:2px solid rgb(221,221,221)"> 方法</th> <th style="padding:8px; text-align:left; line-height:1.42857; vertical-align:bottom; border-top:0px; border-bottom:2px solid rgb(221,221,221)"> 说明</th> </tr> </thead> <tbody style=""> <tr style=""> <td style="padding:8px; line-height:1.42857; vertical-align:top; border-top:1px solid rgb(221,221,221)"> getParent()</td> <td style="padding:8px; line-height:1.42857; vertical-align:top; border-top:1px solid rgb(221,221,221)"> 返回该类加载器的父类加载器</td> </tr> <tr style=""> <td style="padding:8px; line-height:1.42857; vertical-align:top; border-top:1px solid rgb(221,221,221)"> loadClass(String name)</td> <td style="padding:8px; line-height:1.42857; vertical-align:top; border-top:1px solid rgb(221,221,221)"> 加载名称为name的类,返回结果是一个<code style="font-family:Menlo,Monaco,Consolas,"Courier New",monospace; font-size:12.6px; padding:2px 4px; color:rgb(199,37,78); background-color:rgb(249,242,244); white-space:nowrap">java.lang.Class</code>实例</td> </tr> <tr style=""> <td style="padding:8px; line-height:1.42857; vertical-align:top; border-top:1px solid rgb(221,221,221)"> findClass(String name)</td> <td style="padding:8px; line-height:1.42857; vertical-align:top; border-top:1px solid rgb(221,221,221)"> 查找名称为name的类,返回结果是一个<code style="font-family:Menlo,Monaco,Consolas,"Courier New",monospace; font-size:12.6px; padding:2px 4px; color:rgb(199,37,78); background-color:rgb(249,242,244); white-space:nowrap">java.lang.Class</code>实例</td> </tr> <tr style=""> <td style="padding:8px; line-height:1.42857; vertical-align:top; border-top:1px solid rgb(221,221,221)"> findLoadedClass(String name)</td> <td style="padding:8px; line-height:1.42857; vertical-align:top; border-top:1px solid rgb(221,221,221)"> 查找名称为name的已经被加载的类,返回结果是一个<code style="font-family:Menlo,Monaco,Consolas,"Courier New",monospace; font-size:12.6px; padding:2px 4px; color:rgb(199,37,78); background-color:rgb(249,242,244); white-space:nowrap">java.lang.Class</code>实例</td> </tr> <tr style=""> <td style="padding:8px; line-height:1.42857; vertical-align:top; border-top:1px solid rgb(221,221,221)"> defineClass(String name, byte[] b, int off, int len)</td> <td style="padding:8px; line-height:1.42857; vertical-align:top; border-top:1px solid rgb(221,221,221)"> 把字节数组b中的内容转换为一个<code style="font-family:Menlo,Monaco,Consolas,"Courier New",monospace; font-size:12.6px; padding:2px 4px; color:rgb(199,37,78); background-color:rgb(249,242,244); white-space:nowrap">java.lang.Class</code>实例,该方法是final的</td> </tr> <tr style=""> <td style="padding:8px; line-height:1.42857; vertical-align:top; border-top:1px solid rgb(221,221,221)"> resolveClass(Class<?> c)</td> <td style="padding:8px; line-height:1.42857; vertical-align:top; border-top:1px solid rgb(221,221,221)"> 链接指定的class</td> </tr> </tbody> </table> 一般来说,如果需要实现自己的类加载器,只需要实现`findClass`方法即可,`loadClass`封装了下面提到的委托机制。 [copycode.gif]: /images/20220711/e472bfbcbeed4e25aa88031e8edf39db.png [132044146448948.png]: /images/20220711/fc88377ec35d495ca3126c145307fa53.png
相关 类加载机制 1.类加载流程 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG 骑猪看日落/ 2022年12月26日 10:26/ 0 赞/ 177 阅读
相关 类加载机制 一、类加载的几个阶段 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9i 末蓝、/ 2022年12月25日 15:54/ 0 赞/ 197 阅读
相关 类加载机制 点击上方“晏霖”,选择“置顶或者星标” 曾经有人关注了我 后来他有了女朋友 1.6类加载机制 1.6.1概述 学习本章前我们要对类文件结构有一个简单的认识,而学 迷南。/ 2022年12月22日 11:16/ 0 赞/ 187 阅读
相关 类加载机制 我们都知道java中比较常提到的一个概念就是类。但是在java机制中,类是怎么运行的呢?下面来看看L: 类被加载到虚拟机到使用,最后被卸载,经历了一下几个步骤: ╰+哭是因爲堅強的太久メ/ 2022年07月13日 09:10/ 0 赞/ 259 阅读
相关 类加载机制 类加载器层次是怎么样的 1. JVM预定义的三种类型类加载器: 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 `<J - 日理万妓/ 2022年07月12日 07:15/ 0 赞/ 284 阅读
相关 类加载机制 类加载器层次是怎么样的 1. JVM预定义的三种类型类加载器: 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 `<J Bertha 。/ 2022年07月12日 07:15/ 0 赞/ 226 阅读
相关 类加载机制 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、 转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。 待我称王封你为后i/ 2022年07月12日 05:59/ 0 赞/ 265 阅读
相关 类加载机制 任何一个类在使用前都要经历过完整的加载,连接和初始化三个类加载步骤。经历过这三个步骤之后类型就能随时随地被使用了。从一个类型被加载进JVM算起,直至最终被卸载出内存为止,它的整 左手的ㄟ右手/ 2022年06月10日 06:47/ 0 赞/ 308 阅读
相关 类加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个`java.lang.Class`对 骑猪看日落/ 2022年05月27日 05:08/ 0 赞/ 303 阅读
相关 类加载机制 java类加载的全过程包含5个步骤: 加载,验证,准备,解析,初始化 而验证,准备,解析又可以合并为一个阶段:连接 怼烎@/ 2021年10月01日 08:26/ 0 赞/ 434 阅读
还没有评论,来说两句吧...