雙親委派機制並不難,初級程序員也能看懂的1個例子

雙親委派機制,是jvm類加載中重要的安全機制。

java虛擬機對class文件採用的是按需加載的方式,也就是說需要使用該類時才會將它的class文件加載到內存生成class對象。而且加載某個類的class文件時,java虛擬機採用的是雙親委派模式,即把請求交給父類處理,它是一種任務委派模式。

首先看一個問題:以下代碼是否會調用我們自己定義的String類

<code>package java.lang;

public class String {
//如果新創建的對象是我們自定義的String,該靜態代碼塊會執行
//控制檯上會打印“自定義的String”
static{
System.out.println("自定義的String");
}
}

package test;
public class StringTest {
public static void main(String[] args) {
String str=new String();
System.out.println("hello");
}
}/<code>

出現的問題:

jdk自帶了java.lang.String,我們也創建了一個java.lang.String,那麼新創建的對象String會是誰的對象呢?

驗證思路:

在我們自定義的String中,添加了靜態代碼塊,如果創建對象,一定會執行打印語句。jdk自帶的java.lang.String在新創建過程中並不會打印任何東西。所以我們只要看控制檯是否有輸出即可,若打印出“自定義的String”,則創建了我們自定義的String,若沒有打印信息,則創建了jdk自帶的String。

雙親委派機制並不難,初級程序員也能看懂的1個例子

運行結果

並沒有打印出“自定義的String‘,所以可以得出結論新創建對象時,jvm加載了自帶的String。

此過程中,就使用到了雙親委派機制。

那麼雙親委派機制如何工作的呢?

工作原理

雙親委派機制並不難,初級程序員也能看懂的1個例子

雙親委派模型

1.如果一個類加載器收到了類加載請求,它並不會自己先去加載,而是先把這個加載任務交給他的父類。

2.如果父類加載器還存在父類,那麼就繼續向上委託任務。

3.如果父類加載器可以完成,父類就去做這個任務,併成功返回;若父類加載器無法完成此加載任務,子類加載器才會嘗試自己去加載

類比上邊的例子

1.當jvm看到String str=new String()時,此時jvm會根據java.lang.String從磁盤中找該類

2.若 系統類加載器 接收到此任務,它會交給它的父類擴展類加載器

3.擴展類加載器 接到此任務,它把這個任務交給引導類加載器

4.引導類加載器 沒有父類了,所以它嘗試加載這個java.lange.String,他從JAVA_HOME/jre/lib/rt.jar、resources.jar找到了這個類,就將其加載返回

5.所以並不會加載我們自定義的String

再舉個生活中的例子

幼兒園小朋友學過孔融讓梨,一天得到一個蘋果,小朋友把蘋果給父母吃,父母又把蘋果給了爺爺奶奶。如果爺爺奶奶吃了,小朋友就沒有蘋果吃了。如果父母把蘋果吃了,小朋友也沒有蘋果吃了。如果爺爺奶奶、父母都不吃,小朋友就可以開心地吃蘋果了。

總結:

類加載器接收到任務,先把任務交給父類,如果父類還有父類,接著向上遞交任務(也可以說委託任務),直到最頂層的類加載器,才開始嘗試處理加載任務,如果處理不了再交給子類處理。

結尾:如果有什麼疑問,可以在下方評論,我會一一作答


分享到:


相關文章: