阿里预面:谈谈你对双亲委派机制的理解?这个名字有啥问题?如何打破?为啥双亲委派?...
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之道公众号
好文章,我在看❤️
以上是关于阿里预面:谈谈你对双亲委派机制的理解?这个名字有啥问题?如何打破?为啥双亲委派?...的主要内容,如果未能解决你的问题,请参考以下文章