阿里预面:谈谈你对双亲委派机制的理解?这个名字有啥问题?如何打破?为啥双亲委派?...

Posted Hollis Chuang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了阿里预面:谈谈你对双亲委派机制的理解?这个名字有啥问题?如何打破?为啥双亲委派?...相关的知识,希望对你有一定的参考价值。

前情回顾

秋招面试中,我每次面试似乎都被问到关于JVM双亲委派的相关问题。

我先考考你你是怎么理解双亲委派机制的?这个名字你有没有觉得有问题?能举个简单例子说明一些双亲委派吗?双亲委派有何好处?如何打破双亲委派?

几乎所有相关问题都列举啦,以上问题我全部有幸被问过。

话不多说,正文开始~

典型案例

我们看如图案例,或许很多小伙伴在初学时可能都犯过。我看一些朋友留言说再学习SpringBoot时也犯过类似错误。

我自定义了一个类 Java.lang.String,然后在 main 方法里打印了一句话,运行直接报错。有小伙伴可能会想,明明类里面定义了main方法,为何报错 “找不到main方法” 。

可以短暂思考一下为何

其实,如果你明白 “双亲委派机制” 那这个问题你便可以很轻松搞懂啦。

首先,运行程序肯定先执行main方法,要执行main方法就得先加载其类,也就是 java.lang.String ,类加载请求来到类加载器,会一层一层往上委派,最终来到引导/启动类加载器(Bootstrap ClassLoader)。

然后该类加载器发现 java.lang.String 是核心API里面的类,是自己管理范畴(加载核心类库(JAVA_HOME/lib 如rt.jar)),于是加载的核心API里面的那个 java.lang.String ,但是这个 String 类里面是没有main方法的,于是报错了。

双亲委派机制

何为双亲委派机制?

通过上述例子,大家应该差不多对 双亲委派机制 有所体会啦,此处再作归纳总结:

我喜欢简单通俗易懂的表达。

含义:类加载请求来了,类加载器自己先不加载,先让父类加载器加载,父类不行自己再来 。

画个图结合理解一下。

顺带说一下这几个加载器的作用(同被考过许多次 阿里 京东):

  • 启动类加载器:加载核心类库(JAVA_HOME/lib 如rt.jar)

  • 扩展类加载器:加载扩展类(JAVA_HOME/jre/lib/ext)

  • 系统类加载器:加载用户类路径ClassPath下的类

  • 用户自定义加载器:继承java.lang.ClassLoader

如何打破双亲加载机制?

自定义类加载器,重写 loadClass 方法、线程上下文类加载器

具体哪里有所体现呢?

Java 涉及 SPI 机制的都用线程上下文类加载器。父类加载器请求子类加载器完成加载动作 SPI机制:为接口找寻服务(jdbc) SPI约定:服务提供者为接口提供接口实现后,会在 jar 包的 META-INF/service/目录下创建一个以服务接口命名的文件。

jdb4.0 使用 SPI 机制,DriverManage r需要去 jar 包下的 META-INF/services/java.sql.Driver 目录下去寻找对应的 Driver 加载,但是 DriverManager 在 rt.jar 中,使用启动类加载器(BootStrapClassLoader),他需要调用服务提供者放在classpath下的类,启动类加载器无法加载,就只得使用线程上下文加载器,让父类加载器调用子类加载器完成,打破了双亲委派机制。

双亲委派机制好处?

还是简单提取关键字,因为本专栏是针对面试的,尽量通俗简介易记

好处:避免类重复加载+防止核心类篡改+安全性

具体体现可以结合本文开头的例子,假想可以篡改核心类,我自己定义一个类植入错误程序就可以使得整个系统崩溃。

你是否觉得 双亲委派 这个名字有问题?

哈哈 其实读完上文这个问题已经很清楚啦,明明是父类委派加载,为啥要叫双亲委派??

官方文档对 双亲委派 解释:

The Java platform uses a delegation model for loading classes. The basic idea is that every class loader has a “parent” class loader. When loading a class, a class loader first “delegates” the search for the class to its parent class loader before attempting to find the class itself.

java平台通过委派模型去加载类。每个类加载器都有一个父加载器。当需要加载类时,会优先委派当前所在的类的加载器的父加载器去加载这个类。如果父加载器无法加载到这个类时,再尝试在当前所在的类的加载器中加载这个类。

所以,java 的 类加载机制 应该叫做 “父委派模型”,不应该叫做“双亲委派机制”。翻译问题吧,我觉得是,不必太过纠结,我想面试官这样问,只是看你是否真正理解双亲委派机制,你就把 双亲委派机制原理 讲给他听就是。

有道无术,术可成;有术无道,止于术

欢迎大家关注Java之道公众号

好文章,我在看❤️

以上是关于阿里预面:谈谈你对双亲委派机制的理解?这个名字有啥问题?如何打破?为啥双亲委派?...的主要内容,如果未能解决你的问题,请参考以下文章

Java基础巩固系列Java双亲委派机制理解

谈谈类加载器

从源码理解双亲委派机制,原来如此简单

谈谈双亲委派模型的第四次破坏-模块化

阿里面试:什么地方违反了双亲委派模型

阿里面试官:双亲委派都不懂就来面Java?