最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一篇文章弄懂JVM類加載機(jī)制過程以及原理

 更新時(shí)間:2023年02月07日 17:03:35   作者:哪?吒  
JVM原理對(duì)于初學(xué)者而言,比較晦澀難以理解,概念繁多又比較抽象,很多時(shí)候感覺看不見摸不著,還不好驗(yàn)證,下面這篇文章主要給大家介紹了關(guān)于如何通過一篇文章弄懂JVM類加載機(jī)制過程及原理的相關(guān)資料,需要的朋友可以參考下

一、做一個(gè)小測(cè)試

通過注釋,標(biāo)注出下面兩個(gè)類中每個(gè)方法的執(zhí)行順序,并寫出studentId的最終值。

package com.nezha.javase;

public class Person1 {

    private int personId;

    public Person1() {
        setId(100);
    }

    public void setId(int id) {
        personId = id;
    }
}
package com.nezha.javase;

public class Student1 extends Person1 {

    private int studentId = 1;

    public Student1() {
    }

    @Override
    public void setId(int id) {
        super.setId(id);
        studentId = id;
    }

    public void getStudentId() {
        System.out.println("studentId = " + studentId);
    }
}
package com.nezha.javase;

public class Test1 {
    public static void main(String[] args) {
        Student1 student = new Student1();
        System.out.println("new Student() 完畢,開始調(diào)用getStudentId()方法");
        student.getStudentId();
    }
}

有興趣的小伙伴試一下,相信我,用System.out.println標(biāo)記一下每個(gè)函數(shù)執(zhí)行的先后順序,如果你全對(duì)了,下面的不用看了,大佬。

二、類的初始化步驟:

  • 初始化父類中的靜態(tài)成員變量和靜態(tài)代碼塊 ;
  • 初始化子類中的靜態(tài)成員變量和靜態(tài)代碼塊 ;
  • 初始化父類的普通成員變量和代碼塊,再執(zhí)行父類的構(gòu)造方法;
  • 初始化子類的普通成員變量和代碼塊,再執(zhí)行子類的構(gòu)造方法;

三、看看你寫對(duì)了沒?

package com.nezha.javase;

public class Person {

    private int personId;

    /**
     * 第一步,走父類無參構(gòu)造函數(shù)
     */
    public Person() {
        // 1、第一步,走父類無參構(gòu)造函數(shù)
        System.out.println("第一步,走父類無參構(gòu)造函數(shù)");
        System.out.println("");
        setId(100);
    }

    /**
     * 第三步,通過super.setId(id);走父類發(fā)方法
     * @param id
     */
    public void setId(int id) {
        System.out.println("第三步,通過super.setId(id);走父類發(fā)方法~~~id="+id);
        personId = id;
        System.out.println("在父類:studentId 被賦值為 " + personId);
        System.out.println("");
    }
}
package com.nezha.javase;

public class Student extends Person {

    private int studentId = 1;

    /**
     * 在走子類無參構(gòu)造函數(shù)前,會(huì)先執(zhí)行子類的普通成員變量初始化
     * 第五步,走子類無參構(gòu)造函數(shù)
     */
    public Student() {
        System.out.println("第五步,在走子類無參構(gòu)造函數(shù)前,會(huì)先執(zhí)行子類的普通成員變量初始化");
        System.out.println("第六步,走子類無參構(gòu)造函數(shù)");
        System.out.println("");
    }

    /**
     * 第二步,走子類方法
     *
     * 走完super.setId(id);,第四步,再回此方法
     * @param id
     */
    @Override
    public void setId(int id) {
        System.out.println("第二步,走子類方法~~id="+id);
        // 3、第三步,走子類方法
        super.setId(id);
        studentId = id;
        System.out.println("第四步,再回此方法,在子類:studentId 被賦值為 " + studentId);
        System.out.println("");
    }

    /**
     * 第六步,走getStudentId()
     */
    public void getStudentId() {
        // 4、打印出來的值是100
        System.out.println("第七步,走getStudentId()");
        System.out.println("studentId = " + studentId);
        System.out.println("");
    }
}
package com.nezha.javase;

public class Test1 {
    public static void main(String[] args) {
        Student1 student = new Student1();
        System.out.println("new Student() 完畢,開始調(diào)用getStudentId()方法");
        // 打印出來的值是100
        System.out.println("#推測(cè)~~打印出來的值是100");
        student.getStudentId();
    }
}

下面通過圖解JVM的方式,分析一下。

四、類的加載過程

1、加載

  • 通過一個(gè)類的全限定名獲取定義此類的二進(jìn)制字節(jié)流;
  • 將這個(gè)字節(jié)流代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu);
  • 在內(nèi)存中生成一個(gè)代表這個(gè)類的java.lang.Class對(duì)象,作為方法區(qū)這個(gè)類的各種數(shù)據(jù)的訪問入口;

2、鏈接

(1)驗(yàn)證(Verify)

  • 目的在于確保Class文件的字節(jié)流中包含信息符合當(dāng)前虛擬機(jī)要求,保證被加載類的正確性,不會(huì)危害虛擬機(jī)自身安全;
  • 主要包括四種驗(yàn)證:文件格式驗(yàn)證、元數(shù)據(jù)驗(yàn)證、字節(jié)碼驗(yàn)證、符號(hào)引用驗(yàn)證;

(2)準(zhǔn)備(Prepare)

  • 為類變量分配內(nèi)存并且設(shè)置該類變量的默認(rèn)初始值;
  • 這里不包含final修飾的static,因?yàn)閒inal在編譯的時(shí)候就會(huì)分配了,準(zhǔn)備階段會(huì)顯示初始化;
  • 這里不會(huì)為實(shí)例變量分配初始化,類變量會(huì)分配在方法區(qū)中,而實(shí)例變量是會(huì)隨著對(duì)象一起分配到堆中;

(3)解析

  • 將常量池內(nèi)的符號(hào)引用轉(zhuǎn)換為直接引用的過程
  • 例如靜態(tài)代碼塊、靜態(tài)變量的顯示賦值
  • 事實(shí)上,解析操作往往會(huì)伴隨著JVM在執(zhí)行完初始化之后在執(zhí)行
  • 符號(hào)引用就是一組符號(hào)來描述所引用的目標(biāo)。符號(hào)引用的字面量形式明確定義在《Java虛擬機(jī)規(guī)范》的Class文件格式中。直接引用就是指- 向目標(biāo)的指針、相對(duì)偏移量或一個(gè)間接定位到目標(biāo)的句柄
  • 解析動(dòng)作主要針對(duì)類或接口、字段、類方法、接口方法、方法類型等。對(duì)常量池中的CONSTANT_Filedref_info、CONSTANT_Class_info、CONSTANT_Methodref_info等。

3、初始化

  • 初始化階段就是執(zhí)行類構(gòu)造器方法的過程;
  • 此方法不需要定義,是javac編譯器自動(dòng)收集類中的所有類變量的賦值動(dòng)作和靜態(tài)代碼塊中的語(yǔ)句合并而來;
  • 構(gòu)造器方法中指令按語(yǔ)句在源文件中出現(xiàn)的順序執(zhí)行;
  • 類構(gòu)造器方法不同于類的構(gòu)造器。構(gòu)造器是虛擬機(jī)視角下的類構(gòu)造器;
  • 若該類具有父類,JVM會(huì)保證子類的類構(gòu)造器執(zhí)行前,父類的類構(gòu)造器已經(jīng)執(zhí)行完畢;
  • 虛擬機(jī)必須保證一個(gè)類的類構(gòu)造器方法在多線程下被同步加鎖;

五、類加載器的分類

JVM類加載器包括兩種,分別為引導(dǎo)類加載器(Bootstrap ClassLoader)和自定義類加載器(User-Defined ClassLoader)。

所有派生于抽象類ClassLoader的類加載器劃分為自定義類加載器。

1、啟動(dòng)類加載器(引導(dǎo)類加載器)

  • 啟動(dòng)類加載器是使用C/C++語(yǔ)言實(shí)現(xiàn)的,嵌套在JVM內(nèi)部;
  • Java的核心類庫(kù)都是使用引導(dǎo)類加載器加載的,比如String;
  • 沒有父加載器;
  • 是擴(kuò)展類加載器和應(yīng)用程序類加載器的父類加載器 ;
  • 出于安全考慮,Bootstrap啟動(dòng)類加載器只加載包名為java、javax、sun等開頭的類 ;

2、擴(kuò)展類加載器

  • java語(yǔ)言編寫
  • 派生于ClassLoader類
  • 父類加載器為啟動(dòng)類加載器
  • 從java.ext.dirs系統(tǒng)屬性所指定的目錄中加載類庫(kù),或從JDK的安裝目錄jre/lib/ext子目錄(擴(kuò)展目錄)下加載類庫(kù)。如果用戶創(chuàng)建的jar放在此目錄下,也會(huì)自動(dòng)由擴(kuò)展類加載器加載

3、應(yīng)用程序類加載器(系統(tǒng)類加載器)

  1. java語(yǔ)言編寫
  2. 派生于ClassLoader類
  3. 父類加載器為擴(kuò)展類加載器
  4. 它負(fù)責(zé)加載環(huán)境變量classpath或系統(tǒng)屬性java.class.path指定路徑下的類庫(kù)
  5. 該類加載器是程序中默認(rèn)的類加載器,一般來說,Java應(yīng)用的類都是由它來完成加載的
  6. 通過ClassLoader.getSystemClassLoader()方法可以獲得該類加載器

六、類加載器子系統(tǒng)的作用

類加載器子系統(tǒng)負(fù)責(zé)從文件系統(tǒng)或網(wǎng)絡(luò)中加載class文件,class文件在文件開頭有特定的文件標(biāo)識(shí)。

ClassLoader只負(fù)責(zé)class文件的加載,至于它是否可以運(yùn)行,則有執(zhí)行引擎決定。

加載的類信息存放于一塊稱為方法區(qū)的內(nèi)存空間。除了類的信息外,方法區(qū)中還會(huì)存放運(yùn)行時(shí)常量池的信息,可能還包括字符串字面量和數(shù)字常量(這部分常量信息是class文件中常量池部分的內(nèi)存映射)。

七、總結(jié)

類的初始化步驟,這看似非常基礎(chǔ)的話題,卻實(shí)打?qū)嵉碾y住了很多人,還總結(jié)了更為深入JVM的類的加載過程、類加載器的分類、類加載器的作用。

到此這篇關(guān)于一篇文章弄懂JVM類加載機(jī)制過程以及原理的文章就介紹到這了,更多相關(guān)JVM類加載機(jī)制過程及原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring整合Quartz開發(fā)代碼實(shí)例

    Spring整合Quartz開發(fā)代碼實(shí)例

    這篇文章主要介紹了Spring整合Quartz開發(fā)代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Java中的布隆過濾器你真的懂了嗎

    Java中的布隆過濾器你真的懂了嗎

    經(jīng)常會(huì)聽到大家說起布隆過濾器,但是很多人都只是聽過名字,卻并不知道其是怎么實(shí)現(xiàn)的。下面將詳細(xì)介紹一下布隆過濾器,并且使用簡(jiǎn)單的代碼演示
    2023-04-04
  • java使用servlet實(shí)現(xiàn)驗(yàn)證碼

    java使用servlet實(shí)現(xiàn)驗(yàn)證碼

    這篇文章主要介紹了java使用servlet實(shí)現(xiàn)驗(yàn)證碼,簡(jiǎn)單實(shí)用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Java正則表達(dá)式工具方法匯總

    Java正則表達(dá)式工具方法匯總

    這篇文章主要介紹了Java正則表達(dá)式工具方法匯總,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Java中字符串去重的特性介紹

    Java中字符串去重的特性介紹

    這篇文章主要介紹了Java中字符串去重的特性,是Java8中引入的一個(gè)新特性,至于是否真的用起來順手就見仁見智了...需要的朋友可以參考下
    2015-07-07
  • Spring Cloud實(shí)戰(zhàn)技巧之使用隨機(jī)端口

    Spring Cloud實(shí)戰(zhàn)技巧之使用隨機(jī)端口

    這篇文章主要給大家介紹了關(guān)于Spring Cloud實(shí)戰(zhàn)技巧之使用隨機(jī)端口的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-06-06
  • 深入解析Java編程中面向字節(jié)流的一些應(yīng)用

    深入解析Java編程中面向字節(jié)流的一些應(yīng)用

    這篇文章主要介紹了Java編程中面向字節(jié)流的一些應(yīng)用,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-10-10
  • 詳解Kotlin:forEach也能break和continue

    詳解Kotlin:forEach也能break和continue

    這篇文章主要介紹了詳解Kotlin:forEach也能break和continue的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Java正則表達(dá)式循環(huán)匹配字符串方式

    Java正則表達(dá)式循環(huán)匹配字符串方式

    這篇文章主要介紹了Java正則表達(dá)式循環(huán)匹配字符串方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 從零開始學(xué)Java之關(guān)系運(yùn)算符

    從零開始學(xué)Java之關(guān)系運(yùn)算符

    今天帶大家復(fù)習(xí)Java關(guān)系運(yùn)算符,文中對(duì)Java運(yùn)算符相關(guān)知識(shí)作了詳細(xì)總結(jié),對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們很有幫助,需要的朋友可以參考下
    2021-08-08

最新評(píng)論

浏阳市| 江华| 红河县| 泰顺县| 蒙自县| 洛南县| 沾益县| 壶关县| 松原市| 竹北市| 宝丰县| 麟游县| 佛山市| 永昌县| 延津县| 东乌珠穆沁旗| 牡丹江市| 襄垣县| 吉林省| 阜平县| 从化市| 龙泉市| 泊头市| 南江县| 枞阳县| 离岛区| 津南区| 临桂县| 晋州市| 嘉禾县| 新沂市| 小金县| 沧源| 罗田县| 岱山县| 闻喜县| 宜君县| 普陀区| 原阳县| 平武县| 方山县|