JVM 原理六:类加载器双亲委托机制详解

>>号外:关注“Java精选”公众号,回复“2021面试题”关键词,领取全套500多份Java面试题文件。

类加载器层级:

类加载器的父类委托机制

在父类委托机制中,各个加载器按照按照父子关系形成树形结构(逻辑意义的树形结构),除了根类加载器之外,其余的类加载器都有且只有一个父加载器。

加载过程举例:
loader1拿到Sample的字节码的时候会把Sample交给loader1的父级加载器【系统类加载器】加载,【系统类加载器】还有一个父级加载器【扩展类加载器】然后将Sample交给了【扩展类加载器】,但是【扩展类加载器】还有一个父级加载器【根类加载器】,最终到了Sample到了【根类加载器】。

由于【根类加载器】是顶层的加载器,所以【根类加载器】尝试加载Sample,但是【根类加载器】只加载规定目录下的类,显然Sample不在指定的目录下,【根类加载器】无法加载它,然后【根类加载器】把Sample交给了【扩展类加载器】。

同样的道理【扩展类加载器】也是只能加载规定目录下的类,Sample不在【扩展类加载器】指定的目录下,从而无法加载,然后把Sample交给了【系统类加载器】,【系统类加载器】的加载目录包含Sample类的字节码,【系统类加载器】完成了Sample的加载,最后结果返回给了loade


上例中【系统类加载器】就是定义类加载器,loader1是初始类加载器。

实例讲解:

public class MyTest7 {
    public static void main(String[] args) throws Exception{
        Class<?> str = Class.forName("java.lang.String");
        System.out.println(str.getClassLoader());//打印null 因为java.lang.String是有根类加载器加载,getClassLoader()方法看下边介绍。

        Class<?> c = Class.forName("com.twodragonlake.jvm.classloader.C");//返回系统类加载器
        System.out.println(c.getClassLoader());
    }
}

class C{

}

打印结果:

null
sun.misc.Launcher$AppClassLoader@18b4aac2

getClassLoader()方法:

/**
* Returns the class loader for the class. Some implementations may use
* null to represent the bootstrap class loader. This method will return
* null in such implementations if this class was loaded by the bootstrap
* class loader.
* 返回这个class的类加载器,有些实现使用null代替bootstrap 加载器,如果这个类的加载器是bootstrap 那么这个方法返回null
*If a security manager is present, and the caller’s class loader is
* not null and the caller’s class loader is not the same as or an ancestor of
* the class loader for the class whose class loader is requested, then
* this method calls the security manager’s {@code checkPermission}
* method with a {@code RuntimePermission(“getClassLoader”)}
* permission to ensure it’s ok to access the class loader for the class.
* 如果使用了安全管理器,调用者的类加载器不是null,并且调用者的类加载器和类的加载器的层次关系不相等,那么就会用RuntimePermission(“getClassLoader”)调用安全管理器的getClassLoader方法来确认是否可以允许这个类的加载器去加载它。
*If this object
* represents a primitive type or void, null is returned.
*
* @return the class loader that loaded the class or interface
* represented by this object.
* 返回加载了当前对象对应类的接口的加载器
* @throws SecurityException
* if a security manager exists and its
* {@code checkPermission} method denies
* access to the class loader for the class.
* @see java.lang.ClassLoader
* @see SecurityManager#checkPermission
* @see java.lang.RuntimePermission
*/
@CallerSensitive
public ClassLoader getClassLoader() {

}

作者:魔鬼_

blog.csdn.net/wzq6578702/article/details/79430576

往期精选  点击标题可跳转

JVM 原理四:接口初始化规则与类加载器准备阶段和初始化阶段的重要意义

JVM 原理三:编译期常量与运行期常量的区别及数组创建本质分析

JVM 原理二:常量的本质含义与反编译及助记符详解

JVM 原理一:类加载器深入解析与阶段分解

Java 中统计代码执行耗时,列举 4 种优雅的解决方案

MySQL 分页使用 limit 和 offset 参数为什么会导致执行变慢?

全网可能是最全的 JAVA 日志框架适配、冲突解决方案

数据库在哪些场景下导致索引失效,索引何时会失效?

为什么 Redis 越来越慢了?延迟问题定位排查与分析

Spring 框架中导致 @Transactional 事务注解 3 种失效场景分析及解决方法

放弃 JDK8 中 StringBuilder,使用 StringJoiner 辅助类,真香!

点个赞,就知道你“在看”!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值