您好,登錄后才能下訂單哦!
好程序員Java學(xué)習(xí)路線(xiàn)分享Java面試題之加載機(jī)制,面試場(chǎng)景:
面試官第一問(wèn):
請(qǐng)問(wèn),我現(xiàn)在編寫(xiě)一個(gè)類(lèi),類(lèi)全名如下:java.lang.String,
我們知道JDK也給我們聽(tīng)過(guò)了一個(gè)java.lang.String,
那么,我們編寫(xiě)的這個(gè)String類(lèi)能否替換到JDK默認(rèn)提供,也就是說(shuō)程序?qū)嶋H運(yùn)行的時(shí)候,會(huì)加載我們的String還是JDK的String?為什么?
如果,你無(wú)法確定?那么第二問(wèn):
了解類(lèi)的加載機(jī)制嗎?知道JDK的類(lèi)加載器嗎?雙親委托機(jī)制說(shuō)說(shuō)看
如果,你還不了解,那么我們聊聊今天的天氣吧!
1,首先,什么是類(lèi)的加載機(jī)制?
JVM使用Java類(lèi)的流程如下:
1,Java源文件----編譯---->class文件
2,類(lèi)加載器ClassLoader會(huì)讀取這個(gè).class文件,并將其轉(zhuǎn)化為java.lang.Class的實(shí)例。有了該實(shí)例,JVM就可以使用他來(lái)創(chuàng)建對(duì)象,調(diào)用方法等操作了。
那么ClassLoader是以一種什么機(jī)制來(lái)加載Class的?
這就是我們要談的類(lèi)的加載機(jī)制!
2,搞清楚這個(gè)問(wèn)題,首先要知道,我們用到的Class文件都有哪些來(lái)源?
1,Java內(nèi)部自帶的核心類(lèi),位于$JAVA_HOME/jre/lib,其中最著名的莫過(guò)于rt.jar
2,Java的擴(kuò)展類(lèi),位于$JAVA_HOME/jre/lib/ext目錄下
3,我們自己開(kāi)發(fā)的類(lèi)或項(xiàng)目開(kāi)發(fā)用到的第三方j(luò)ar包,位于我們項(xiàng)目的目錄下,比如WEB-INF/lib目錄
3,那么,針對(duì)這些Class,JDK是怎么分工的?誰(shuí)來(lái)加載這些Class?
針對(duì)不同的來(lái)源,Java分了不同的ClassLoader來(lái)加載
1,Java核心類(lèi),這些Java運(yùn)行的基礎(chǔ)類(lèi),由一個(gè)名為BootstrapClassLoader加載器負(fù)責(zé)加載。這個(gè)類(lèi)加載器被稱(chēng)為“根加載器或引導(dǎo)加載器”
注意:BootstrapClassLoader不繼承ClassLoader,是由JVM內(nèi)部實(shí)現(xiàn)。法力無(wú)邊,所以你通過(guò)java程序訪(fǎng)問(wèn)不到,得到的是null。
2,Java擴(kuò)展類(lèi),是由ExtClassLoader負(fù)責(zé)加載,被稱(chēng)為“擴(kuò)展類(lèi)加載器”。
3,項(xiàng)目中編寫(xiě)的類(lèi),是由AppClassLoader來(lái)負(fù)責(zé)加載,被稱(chēng)為“系統(tǒng)類(lèi)加載器”。
4, 那憑什么,我就知道這個(gè)類(lèi)應(yīng)該由老大BootStrapClassLoader來(lái)加載?
這里面就要基于雙親委托機(jī)制?
所謂雙親委托機(jī)制,就是加載一個(gè)類(lèi),會(huì)先獲取到一個(gè)系統(tǒng)類(lèi)加載器AppClassLoader的實(shí)例,然后往上層層請(qǐng)求,先由BootstarpClassLoader去加載,
如果BootStrapClassLoader發(fā)現(xiàn)沒(méi)有,再下發(fā)給ExtClassLoader去加載,還是沒(méi)有,才由AppClassLoader去加載。
如果還是沒(méi)有,則報(bào)錯(cuò)
5,所以,上述問(wèn)題的答案你清楚了嗎?
JDK提供java.lang.String類(lèi),默認(rèn)在rt.jar這個(gè)包里面,所以,默認(rèn)會(huì)由BootstarpClassLoader加載,
所以,我們自己編寫(xiě)的java.lang.String,都沒(méi)有機(jī)會(huì)被加載到
6,給兩段程序看看,類(lèi)加載器的關(guān)系
案例1:創(chuàng)建一個(gè)自己的類(lèi),然后打印其類(lèi)加載器
public class ClassLoaderTest {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> clazz = Class.forName("com.qianfeng.thread.client.Programmer");
ClassLoader classLoader = clazz.getClassLoader();
System.out.println(classLoader.getClass().getSimpleName());
}
}
案例2:打印其雙親類(lèi)加載器信息
while(classLoader.getParent() != null){
classLoader = classLoader.getParent();
System.out.println("-->"+classLoader.getClass().getSimpleName());
}
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。