欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JVM類加載之雙親委派機制解讀

 更新時間:2023年12月04日 09:26:58   作者:w7h1te  
這篇文章主要介紹了JVM類加載之雙親委派機制解讀,類加載階段分為加載、連接、初始化三個階段,而加載階段需要通過類的全限定名來獲取定義了此類的二進制字節(jié)流,Java特意把這一步抽出來用類加載器來實現(xiàn),需要的朋友可以參考下

前言

在面試過程中:也會被問到關(guān)于如何理解雙親委派模型這樣的問題,接下來就通過這篇文章往明白了解一下。

我們首先需要了解一下類加載階段

類的加載階段

類加載階段分為加載、連接、初始化三個階段,而加載階段需要通過類的全限定名來獲取定義了此類的二進制字節(jié)流。Java特意把這一步抽出來用類加載器來實現(xiàn)。把這一步驟抽離出來使得應用程序可以按需自定義類加載器。并且得益于類加載器,OSGI、熱部署等領(lǐng)域才得以在JAVA中得到應用。

類加載器除了能用來加載類,還能用來作為類的層次劃分。Java自身提供了3種類加載器

類加載器

1、啟動類加載器(Bootstrap ClassLoader),它是屬于虛擬機自身的一部分,用C++實現(xiàn)的,主要負責加載<JAVA_HOME>\lib目錄中或被-Xbootclasspath指定的路徑中的并且文件名是被虛擬機識別的文件。它等于是所有類加載器的爸爸。

2、擴展類加載器(Extension ClassLoader),它是Java實現(xiàn)的,獨立于虛擬機,主要負責加載<JAVA_HOME>\lib\ext目錄中或被java.ext.dirs系統(tǒng)變量所指定的路徑的類庫。

3、應用程序類加載器(Application ClassLoader),它是Java實現(xiàn)的,獨立于虛擬機。主要負責加載用戶類路徑(classPath)上的類庫,如果我們沒有實現(xiàn)自定義的類加載器那這玩意就是我們程序中的默認加載器。

什么是雙親委派機制

上圖:

在這里插入圖片描述

簡單來說:如果一個類加載器需要加載類,那么首先它會把這個類請求委派給父類加載器去完成,每一層都是如此。一直遞歸到頂層,當父加載器無法完成這個請求時,子類才會嘗試去加載。這里的雙親其實就指的是父類,沒有mother。父類也不是我們平日所說的那種繼承關(guān)系,只是調(diào)用邏輯是這樣。

也就是當類加載器收到類加載的請求時候會首先調(diào)用父類(ClassLoader)的findLoadedClass方法,判斷類是否加載過,如果已經(jīng)加載過則直接返回,否則會將加載任務委托給成員變量parent,并不是指的父類。parent加載器在收到類加載請求后,也會先判斷需要加載的類是否已經(jīng)加載過,如果加載過則結(jié)束,否則也會將加載任務委托給成員變量parent去進行類加載。這里是一個循環(huán)過程,直到將加載任務委托給Bootstrap ClassLoader 結(jié)束,如果Bootstrap ClassLoader也沒有找到則交給各個子類自己加載,一直到最后,如果沒有任何類加載器能加載則會拋出ClassNotFoundException。

為什么要設計雙親委派機制?

  • 沙箱安全機制

自己寫的java.lang.String.class類不會被加載,這樣可以防止核心API庫被隨意篡改。 為了不讓我們寫String類,類加載采用委托機制,這樣可以保證爸爸們優(yōu)先,爸爸們能找到的類,兒子就沒有機會加載。而String類是Bootstrap加載器加載的,就算自己重寫,也總是使用Java系統(tǒng)提供的String,自己寫的String類根本沒有機會得到加載。

  • 避免類的重復加載

當父親已經(jīng)加載了該類, 就沒必要子classLoader再加載一次,保證被加載的唯一性。

引申內(nèi)容

JVM 類加載器和類本身一同確立類在Java虛擬機中的唯一性

問題:由不同類加載器加載同一個類,實例化為對象。使用instanceof判斷該對象與該類的歸屬,請問結(jié)果是true還是false?

答案是false。

驗證解析

import java.io.IOException;
import java.io.InputStream;
public class ClassLoaderTest {
    public static void main(String[] args) throws Exception {
        ClassLoader myLoader = new ClassLoader() {
            @SuppressWarnings("ResultOfMethodCallIgnored")
            @Override
            public Class<?> loadClass(String name) throws ClassNotFoundException {
                try {
                    String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
                    InputStream is = getClass().getResourceAsStream(fileName);
                    if (is == null) {
                        return super.loadClass(name);
                    }
                    byte[] b = new byte[is.available()];
                    is.read(b);
                    return defineClass(name, b, 0, b.length);
                } catch (IOException e) {
                    throw new ClassNotFoundException(name);
                }
            }
        };
        Object obj = myLoader.loadClass("Practice.Java.ClassLoaderTest").newInstance();
        System.out.println(obj.getClass());
        System.out.println(obj instanceof Practice.Java.ClassLoaderTest);
    }
}

輸出結(jié)果:

class Practice.Java.ClassLoaderTest
false

原因

對于任意一個類,都需要由加載它的類加載器和這個類本身一同確立其在Java虛擬機中的唯一性,每一個類加載器,都擁有一個獨立的類名稱空間。這句話可以表達得更通俗一些:比較兩個類是否“相等”,只有在這兩個類是由同一個類加載器加載的前提下才有意義,否則,即使這兩個類來源于同一個Class文件,被同一個虛擬機加載,只要加載它們的類加載器不同,那這兩個類就必定不相等。

結(jié)果分析

兩行輸出結(jié)果中,從第一句可以看出,這個對象確實是類Practice.Java.ClassLoaderTest實例化出來的對象,但從第二句可以發(fā)現(xiàn),這個對象與類Practice.Java.ClassLoaderTest做所屬類型檢查的時候卻返回了false。

這是因為虛擬機中存在了兩個ClassLoaderTest類,一個是由系統(tǒng)應用程序類加載器加載的,另外一個是由我們自定義的類加載器加載的。雖然都來自同一個Class文件,但依然是兩個獨立的類,做對象所屬類型檢查時結(jié)果自然為false。

結(jié)論

Java類加載器這種特性可以簡單的總結(jié)為命名空間。

即在 Java 虛擬機中,類的唯一性是由類加載器實例以及類的全名一同確定的。即便是同一串字節(jié)流,經(jīng)由不同的類加載器加載,也會得到兩個不同的類。

到此這篇關(guān)于JVM類加載之雙親委派機制解讀的文章就介紹到這了,更多相關(guān)JVM雙親委派機制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java8?stream流分組groupingBy的使用方法代碼

    Java8?stream流分組groupingBy的使用方法代碼

    對于java8的新特性groupingBy方法,相信有很多人都在工作中用過,這篇文章主要給大家介紹了關(guān)于Java8?stream流分組groupingBy的使用方法,需要的朋友可以參考下
    2024-01-01
  • IDEA(jetbrain通用)使用教程圖解

    IDEA(jetbrain通用)使用教程圖解

    本文通過圖文并茂的形式給大家介紹了IDEA(jetbrain通用)使用教程,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-09-09
  • SpringMVC整合websocket實現(xiàn)消息推送及觸發(fā)功能

    SpringMVC整合websocket實現(xiàn)消息推送及觸發(fā)功能

    這篇文章主要為大家詳細介紹了SpringMVC整合websocket實現(xiàn)消息推送及觸發(fā)功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • springBoot Junit測試用例出現(xiàn)@Autowired不生效的解決

    springBoot Junit測試用例出現(xiàn)@Autowired不生效的解決

    這篇文章主要介紹了springBoot Junit測試用例出現(xiàn)@Autowired不生效的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • JUnit中獲取測試類及方法的名稱實現(xiàn)方法

    JUnit中獲取測試類及方法的名稱實現(xiàn)方法

    這篇文章主要介紹了JUnit中獲取測試類及方法的名稱實現(xiàn)方法,本文使用了JUnit中提供的TestName實現(xiàn),不過還有一些編程細節(jié)需要注意,需要的朋友可以參考下
    2015-06-06
  • Spring運行時動態(tài)注冊bean的方法

    Spring運行時動態(tài)注冊bean的方法

    這篇文章主要介紹了Spring運行時動態(tài)注冊bean的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • Java基礎--反射機制

    Java基礎--反射機制

    本文主要介紹了Java反射機制的相關(guān)知識。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-03-03
  • MyBatis快速入門之環(huán)境搭建和單表映射

    MyBatis快速入門之環(huán)境搭建和單表映射

    一說起對象關(guān)系映射框架,大家第一時間想到的肯定是Hibernate。Hibernate作為一個著名的框架,功能十分強大。但是由于Hibernate如此強大的功能,導致了它的缺點。好吧,不多說了,具體詳情大家通過本文一起學習吧
    2017-03-03
  • mybatis中關(guān)于mapper的使用以及注意事項

    mybatis中關(guān)于mapper的使用以及注意事項

    這篇文章主要介紹了mybatis中關(guān)于mapper的使用以及注意事項,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • java fastdfs客戶端使用實例代碼

    java fastdfs客戶端使用實例代碼

    這篇文章主要介紹了java fastdfs客戶端使用實例代碼,簡單介紹了FastDFS的概念和架構(gòu),然后分享了實例代碼,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01

最新評論