阿里預(yù)面:談?wù)勀銓﹄p親委派機(jī)制的理解?這個(gè)名字有啥問題?如何打破?為啥雙親委派?
前情回顧
秋招面試中,我每次面試似乎都被問到關(guān)于JVM雙親委派的相關(guān)問題。
我先考考你:你是怎么理解雙親委派機(jī)制的?這個(gè)名字你有沒有覺得有問題?能舉個(gè)簡單例子說明一些雙親委派嗎?雙親委派有何好處?如何打破雙親委派?
幾乎所有相關(guān)問題都列舉啦,以上問題我全部有幸被問過。
話不多說,正文開始~
典型案例
我們看如圖案例,或許很多小伙伴在初學(xué)時(shí)可能都犯過。我看一些朋友留言說再學(xué)習(xí)SpringBoot時(shí)也犯過類似錯誤。
我自定義了一個(gè)類 Java.lang.String,然后在 main 方法里打印了一句話,運(yùn)行直接報(bào)錯。有小伙伴可能會想,明明類里面定義了main方法,為何報(bào)錯 “找不到main方法” 。
可以短暫思考一下為何?

其實(shí),如果你明白 “雙親委派機(jī)制” 那這個(gè)問題你便可以很輕松搞懂啦。
首先,運(yùn)行程序肯定先執(zhí)行main方法,要執(zhí)行main方法就得先加載其類,也就是 java.lang.String ,類加載請求來到類加載器,會一層一層往上委派,最終來到引導(dǎo)/啟動類加載器(Bootstrap ClassLoader)。
然后該類加載器發(fā)現(xiàn) java.lang.String 是核心API里面的類,是自己管理范疇(加載核心類庫(JAVA_HOME/lib 如rt.jar)),于是加載的核心API里面的那個(gè) java.lang.String ,但是這個(gè) String 類里面是沒有main方法的,于是報(bào)錯了。
雙親委派機(jī)制
何為雙親委派機(jī)制?
通過上述例子,大家應(yīng)該差不多對 雙親委派機(jī)制 有所體會啦,此處再作歸納總結(jié):
我喜歡簡單通俗易懂的表達(dá)。
含義:類加載請求來了,類加載器自己先不加載,先讓父類加載器加載,父類不行自己再來 。
畫個(gè)圖結(jié)合理解一下。
順帶說一下這幾個(gè)加載器的作用(同被考過許多次 阿里 京東):
啟動類加載器:加載核心類庫(JAVA_HOME/lib 如rt.jar) 擴(kuò)展類加載器:加載擴(kuò)展類(JAVA_HOME/jre/lib/ext) 系統(tǒng)類加載器:加載用戶類路徑ClassPath下的類 用戶自定義加載器:繼承java.lang.ClassLoader
具體哪里有所體現(xiàn)呢?jar 包的 META-INF/service/目錄下創(chuàng)建一個(gè)以服務(wù)接口命名的文件。META-INF/services/java.sql.Driver 目錄下去尋找對應(yīng)的 Driver 加載,但是 DriverManager 在 rt.jar 中,使用啟動類加載器(BootStrapClassLoader),他需要調(diào)用服務(wù)提供者放在classpath下的類,啟動類加載器無法加載,就只得使用線程上下文加載器,讓父類加載器調(diào)用子類加載器完成,打破了雙親委派機(jī)制。本專欄是針對面試的,盡量通俗簡介易記。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 的 類加載機(jī)制 應(yīng)該叫做 “父委派模型”,不應(yīng)該叫做“雙親委派機(jī)制”。翻譯問題吧,我覺得是,不必太過糾結(jié),我想面試官這樣問,只是看你是否真正理解雙親委派機(jī)制,你就把 雙親委派機(jī)制原理 講給他聽就是。
有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)
歡迎大家關(guān)注Java之道公眾號
好文章,我在看??
