中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中類加載機制的實例講解

發布時間:2021-08-02 09:28:54 來源:億速云 閱讀:116 作者:chen 欄目:開發技術

這篇文章主要介紹“Java中類加載機制的實例講解”,在日常操作中,相信很多人在Java中類加載機制的實例講解問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java中類加載機制的實例講解”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

1.類加載

<1>.父子類執行的順序

1.父類的靜態變量和靜態代碼塊(書寫順序)

2.子類的靜態變量和靜態代碼塊(書寫順序)

3.父類的實例代碼塊(書寫順序)

4.父類的成員變量和構造方法

5.子類的實例代碼塊

6.子類的成員變量和構造方法

<2>類加載的時機

如果類沒有進行初始化,則需要先進行初始化,虛擬機規范則是嚴格規定有且只有5種情況必須先對類進行初始化(而加載,驗證,準備要在這個之前開始)

1.創建類的實例(new的方式),訪問某個類的靜態變量,或者對該靜態變量賦值,調用類的靜態方法

2.反射的方式

3.初始化某個類的子類,則其父類也會被初始化

4.java虛擬機啟動時被標記為啟動類的類,直接使用java.exe來運行的某個主類(如main類)

5.使用jdk1.7的動態語言支持時

<3>類的生命周期

七個階段:加載,驗證,準備,解析,初始化,使用和卸載。其中驗證,準備和解析三個部分被稱為連接

Java中類加載機制的實例講解

解析階段在某些情況下可以在初始化階段之后再進行,這是為了支持java語言的運行時綁定(動態綁定)

<4>類加載的過程

接下來我們詳細講解一下Java虛擬機中類加載的全過程,也就是加載、驗證、準備、解析和初始化這5個階段所執行的具體動作。

1.加載

<1>通過一個類的全限定名來獲取定義此類的二進制字節流。

<2>將這個字節流所代表的靜態存儲結構轉化為方法區的運行時數據結構。

<3>在內存中生成一個代表這個類的java.lang.Class對象,作為方法區這個類的各種數據的訪問入口。

2.驗證

這一階段的目的是為了確保Class文件的字節流中包含的信息符合當前虛擬機的要求,并且不會危害虛擬機自身的安全。

3.準備

準備階段是正式為類變量分配內存并設置類變量初始值的階段,這些變量所使用的內存都將在方法區中進行分配。

假設一個類變量的定義為:

public static int value=123;

那變量value在準備階段過后的初始值為0而不是123,因為這時候尚未開始執行任何Java方法,而把value賦值為123的putstatic指令是程序被編譯后,存放于類構造器()方法之中,所以把value賦值為123的動作將在初始化階段才會執行。

4.解析

虛擬機將常量池內的符號引用替換為直接引用的過程。

符號引用:符號引用與虛擬機實現的內存布局無關,引用的目標并不一定已經加載到內存中。

直接引用:直接引用是和虛擬機實現的內存布局相關的。如果有了直接引用,那引用的目標必定已經在內存中存在。

5.初始化

在準備階段,變量已經賦過一次系統要求的初始值,而在初始化階段,則根據程序員通過程序制定的主觀計劃去初始化類變量和其他資源,或者可以從另外一個角度來表達:初始化階段是執行類構造器()方法的過程。

了解:

()方法是由編譯器自動收集類中的所有類變量的賦值動作和靜態語句塊(static{}塊)中的語句合并產生的,編譯器收集的順序是由語句在源文件中出現的順序所決定的,靜態語句塊中只能訪問到定義在靜態語句塊之前的變量,定義在它之后的變量,在前面的靜態語句塊可以賦值,但是不能訪問:

public class Test{
    static{
        i=0; //給變量賦值可以正常編譯通過
        System.out.print(i); //這句編譯器會提示"非法向前引用"
    }
    static int i=1;
}

1.()方法(Class類的構造方法)與類的構造函數(或者說實例構造器()方法)不同,它不需要顯式地調用父類構造器,虛擬機會保證在子類的()方法執行之前,父類的()方法已經執行完畢。因此在虛擬機中第一個被執行的()方法的類肯定是java.lang.Object。

2.()方法對于類或接口來說并不是必需的,如果一個類中沒有靜態語句塊,也沒有對變量的賦值操作,那么編譯器可以不為這個類生成()方法。

3.接口中定義的變量使用時,接口才會初始化:接口中不能使用靜態語句塊,但仍然有變量初始化的賦值操作,因此接口與類一樣都會生()方法。但接口與類不同的是,執行接口的()方法不需要先執行父接口的()方法。只有當父接口中定義的變量使用時,父接口才會初始化。另外,接口的實現類在初始化時也一樣不會執行接口的()方法。

4.虛擬機會保證一個類的()方法在多線程環境中被正確地加鎖、同步,如果多個線程同時去初始化一個類,那么只會有一個線程去執行這個類的()方法,其他線程都需要阻塞等待,直到活動線程執行()方法完畢。如果在一個類的()方法中有耗時很長的操作,就可能造成多個進程阻塞,在實際應用中這種阻塞往往是很隱蔽的。

<5>類加載器

類加載器可以分為:啟動類加載器、擴展類加載器、應用程序類加載器、自定義類加載器。他們的關系一般如下:

Java中類加載機制的實例講解

1.啟動類加載器(BootstrapClassLoader)
這個類由C++語言實現,是虛擬機自身的一部分,并不繼承ClassLoader,不能操作它。用來加載Java的核心類。

2.擴展類加載器(ExtClassLoader)
這個類加載器是在類sun.misc.Launcher$ExtClassLoader中以Java代碼的形式實現的。它負責加載<JAVA_HOME>\lib\ext目錄中,或者被java.ext.dirs系統變量所指定的路徑中所有的類庫。

3.應用程序類加載器(AppClassLoader)
它負責在 JVM 啟動時加載來自 Java 命令的 -classpath 或者 -cp 選項、java.class.path 系統屬性指定的 jar 包和類路徑。在應用程序代碼里可以通過 ClassLoader 的靜態方法 getSystemClassLoader() 來獲取應用類加載器。如果沒有特別指定,則在沒有使用自定義類加載器情況下,用戶自定義的類都由此加載器加載。

4.2 自定義加載器
用戶自定義了類加載器,則自定義類加載器都以應用類加載器作為父加載器。應用類加載器的父類加載器為擴展類加載器。這些類加載器是有層次關系的,啟動加載器又叫根加載器,是擴展加載器的父加載器

<6>類加載機制——雙親委派模型

雙親委派模型的過程:如果一個類加載器收到了類加載的請求,它首先不會自己嘗試加載這個類,而是把這個請求委派給父類加載器去完成,每一層次的類加載器都是如此,因此所有的加載請求信息最終都會傳送到最頂層的啟動類加載器中,只有當父加載器反饋自己無法完成這個加載請求(即它的搜索范圍沒有找到所需要的類)時,子加載器才會嘗試自己去完成加載

先查找,再進行加載

(1)從下往上找

(2)從上往下加載

雙親委派模型的好處:雙親委派模型對于java程序的穩定運行極為重要

劣勢:無法滿足靈活的類加載方式。(解決方案:自己重寫loadClass破壞雙親委派模型 例如SPI機制)

到此,關于“Java中類加載機制的實例講解”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新闻| 平乐县| 万荣县| 双辽市| 含山县| 平阴县| 南投县| 南丹县| 绥化市| 石泉县| 嘉定区| 英德市| 北川| 安庆市| 合作市| 洞头县| 永年县| 宁海县| 开封市| 宾川县| 秦皇岛市| 漠河县| 酒泉市| 萨迦县| 西安市| 彭州市| 开平市| 平舆县| 河源市| 梨树县| 宕昌县| 望江县| 太和县| 靖宇县| 高尔夫| 彭山县| 曲周县| 盐源县| 凌源市| 常山县| 灵石县|