阿里预面:谈谈你对双亲委派机制的理解?这个名字有啥问题?如何打破?为啥双亲委派?
前情回顾
秋招面试中,我每次面试似乎都被问到关于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
具体哪里有所体现呢?
jar
包的 META-INF/service/
目录下创建一个以服务接口命名的文件。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之道公众号
好文章,我在看❤️