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

JVM核心教程之JVM運行與類加載全過程詳解

 更新時間:2018年04月27日 10:44:13   作者:AskHarries  
我們都知道一個java程序運行要經(jīng)過編譯和執(zhí)行,但是這太概括了,中間還有很多步驟,下面這篇文章主要給大家介紹了關(guān)于JVM核心教程之JVM運行與類加載全過程的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。

為什么要使用類加載器?

Java語言里,類加載都是在程序運行期間完成的,這種策略雖然會令類加載時稍微增加一些性能開銷,但是會給java應(yīng)用程序提供高度的靈活性。例如:

1.編寫一個面向接口的應(yīng)用程序,可能等到運行時再指定其實現(xiàn)的子類;

2.用戶可以自定義一個類加載器,讓程序在運行時從網(wǎng)絡(luò)或其他地方加載一個二進(jìn)制流作為程序代碼的一部分;(這個是Android插件化,動態(tài)安裝更新apk的基礎(chǔ))

為什么研究類加載全過程?

  • 有助于連接JVM運行過程
  • 更深入了解java動態(tài)性(解熱部署,動態(tài)加載),提高程序的靈活性

類加載機(jī)制

JVM把class文件加載到內(nèi)存,并對數(shù)據(jù)進(jìn)行校驗、解析和初始化,最終形成JVM可以直接使用的java類型的全過程。

加載

將class文件字節(jié)碼內(nèi)容加載到內(nèi)存中,并將這些靜態(tài)數(shù)據(jù)轉(zhuǎn)換成方法區(qū)中的運行時數(shù)據(jù)結(jié)構(gòu),在堆中生成一個代表這個類的java.lang.Class對象,作為方法區(qū)類數(shù)據(jù)的訪問入口,這個過程需要類加載器參與。

鏈接

將java類的二進(jìn)制代碼合并到JVM的運行狀態(tài)之中的過程

  • 驗證: 確保加載的類信息符合JVM規(guī)范,沒有安全方面的問題
  • 準(zhǔn)備: 正式為類變量(static變量)分配內(nèi)存并設(shè)置類變量初始值的階段,這些內(nèi)存都將在方法去中進(jìn)行分配
  • 解析: 虛擬機(jī)常量池的符號引用替換為字節(jié)引用過程

初始化

  • 初始化階段是執(zhí)行類構(gòu)造器<clinit>()方法的過程。類構(gòu)造器<clinit>()方法是由編譯器自動收藏類中的所有類變量的賦值動作和靜態(tài)語句塊(static塊)中的語句合并產(chǎn)生
  • 當(dāng)初始化一個類的時候,如果發(fā)現(xiàn)其父類還沒有進(jìn)行過初始化,則需要先觸發(fā)其父類的初始化
  • 虛擬機(jī)會保證一個類的<clinit>()方法在多線程環(huán)境中被正確加鎖和同步
  • 當(dāng)范圍一個Java類的靜態(tài)域時,只有真正聲名這個域的類才會被初始化

例1:

public class Demo01 {
 public static void main(String[] args) {
  A a = new A();
  System.out.println(a.width);
 }
}

class A{
 public static int width=100; //靜態(tài)變量,靜態(tài)域 field
 static{
  System.out.println("靜態(tài)初始化類A");
  width = 300 ;
 }
 public A() {
  System.out.println("創(chuàng)建A類的對象");
 }
}

分析:


說明:

內(nèi)存中存在棧、堆(放創(chuàng)建好的對象)、方法區(qū)(實際也是一種特殊堆)

1、JVM加載Demo01時候,首先在方法區(qū)中形成Demo01類對應(yīng)靜態(tài)數(shù)據(jù)(類變量、類方法、代碼…),同時在堆里面也會形成java.lang.Class對象(反射對象),代表Demo01類,通過對象可以訪問到類二進(jìn)制結(jié)構(gòu)。然后加載變量A類信息,同時也會在堆里面形成a對象,代表A類。

2、main方法執(zhí)行時會在棧里面形成main方法棧幀,一個方法對應(yīng)一個棧幀。如果main方法調(diào)用了別的方法,會在棧里面挨個往里壓,main方法里面有個局部變量A類型的a,一開始a值為null,通過new調(diào)用類A的構(gòu)造器,棧里面生成A()方法同時堆里面生成A對象,然后把A對象地址付給棧中的a,此時a擁有A對象地址。

3、當(dāng)調(diào)用A.width時,調(diào)用方法區(qū)數(shù)據(jù)。

當(dāng)類被引用的加載,類只會加載一次

類的主動引用(一定會發(fā)生類的初始化)

  • new一個類的對象
  • 調(diào)用類的靜態(tài)成員(除了final常量)和靜態(tài)方法
  • 使用java.lang.reflect包的方法對類進(jìn)行反射調(diào)用
  • 當(dāng)虛擬機(jī)啟動,java Demo01,則一定會初始化Demo01類,說白了就是先啟動main方法所在的類
  • 當(dāng)初始化一個類,如果其父類沒有被初始化,則先初始化它父類

類的被動引用(不會發(fā)生類的初始化)

  • 當(dāng)訪問一個靜態(tài)域時,只有真正聲名這個域的類才會被初始化
  • 通過子類引用父類的靜態(tài)變量,不會導(dǎo)致子類初始化
  • 通過數(shù)組定義類的引用,不會觸發(fā)此類初始化
  • 引用常量不會觸發(fā)此類的初始化(常量在編譯階段就存入調(diào)用類的常量池中了)

例2:

public class Demo01 {
 static{
  System.out.println("靜態(tài)初始化Demo01");
 }
 
 
 public static void main(String[] args) throws Exception {
  System.out.println("Demo01的main方法!");
  System.out.println(System.getProperty("java.class.path"));
  
  //主動引用
//  new A();
//  System.out.println(A.width);
//  Class.forName("com.sinosoft.test.A");
  
  
  //被動引用
//  System.out.println(A.MAX);
//  A[] as = new A[10];
  System.out.println(B.width);//B類不會被加載
  
 }
}

class B extends A {
 static {
  System.out.println("靜態(tài)初始化B");
 }
}

class A extends A_Father {
 public static int width=100; //靜態(tài)變量,靜態(tài)域 field
 public static final int MAX=100; 
 
 static {
  System.out.println("靜態(tài)初始化類A");
  width=300;
 }
 public A(){
  System.out.println("創(chuàng)建A類的對象");
 }
}

class A_Father extends Object {
 static {
  System.out.println("靜態(tài)初始化A_Father");
 }
}

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • springboot如何通過SSH連接遠(yuǎn)程服務(wù)器

    springboot如何通過SSH連接遠(yuǎn)程服務(wù)器

    這篇文章主要介紹了springboot如何通過SSH連接遠(yuǎn)程服務(wù)器問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Java SwingWorkder使用實例

    Java SwingWorkder使用實例

    最近在學(xué)習(xí)Swing,我們都知道在UI表現(xiàn)線程里面長時間執(zhí)行操作時,畫面會假死,為了能夠讓費時操作不影響畫面表現(xiàn),就需要用多線程了
    2014-04-04
  • 詳細(xì)介紹Java關(guān)鍵字throw?throws?Throwable的用法與區(qū)別

    詳細(xì)介紹Java關(guān)鍵字throw?throws?Throwable的用法與區(qū)別

    這篇文章主要介紹了java中throws與throw及Throwable的用法和區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • spring?boot如何配置靜態(tài)路徑詳解(404出現(xiàn)的坑)

    spring?boot如何配置靜態(tài)路徑詳解(404出現(xiàn)的坑)

    這篇文章主要給大家介紹了關(guān)于spring?boot如何配置靜態(tài)路徑的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-02-02
  • java.lang.FileNotFoundException 異常的正確解決方法(親測有效)

    java.lang.FileNotFoundException 異常的正確解決方法(親測有效)

    java.io.FileNotFoundException是一個在文件操作過程中常見的異常,它屬于IOException的一個子類,這篇文章主要介紹了java.lang.FileNotFoundException 異常的正確解決方法(親測有效),需要的朋友可以參考下
    2024-01-01
  • Sublime Text 打開Java文檔中文亂碼的解決方案

    Sublime Text 打開Java文檔中文亂碼的解決方案

    這篇文章主要介紹了Sublime Text 中文亂碼的解決方案,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-12-12
  • Spring?Bean的8種加載方式總結(jié)

    Spring?Bean的8種加載方式總結(jié)

    以前學(xué)習(xí)Spring框架的時候,總結(jié)了幾種Bean的加載方式,不過老師說還有其它的加載方式,以下八種并不是全部,但也足以用來做很多事情了,希望對大家有所幫助
    2022-10-10
  • request如何獲取完整url(包括域名、端口、參數(shù))

    request如何獲取完整url(包括域名、端口、參數(shù))

    這篇文章主要介紹了request如何獲取完整url(包括域名、端口、參數(shù))問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • JavaWeb會話技術(shù)詳解與案例

    JavaWeb會話技術(shù)詳解與案例

    會話技術(shù):在Web開發(fā)中,服務(wù)器跟蹤用戶信息的奇數(shù)稱為會話技術(shù)。會話:指的是一個客戶端與服務(wù)器發(fā)生的一系列請求和響應(yīng)的過程。由于請求包含的信息,在請求被銷毀后也就不存在,多次讓用戶輸入賬號密碼,會影響用戶的使用體驗感,基于此,產(chǎn)生了cookie和session技術(shù)
    2021-11-11
  • SpringBoot集成ECDH密鑰交換的方法

    SpringBoot集成ECDH密鑰交換的方法

    ECDH密鑰交換算法通過橢圓曲線和Diffie-Hellman方法生成共享密鑰,用于前端和后端之間的AES加密通信,前端使用elliptic.js生成密鑰對,后端使用crypto-js.min.js進(jìn)行AES加密,本文給大家介紹SpringBoot集成ECDH密鑰交換的相關(guān)知識,感興趣的朋友一起看看吧
    2025-01-01

最新評論

锡林浩特市| 清水河县| 德令哈市| 泰来县| 阿拉善左旗| 库尔勒市| 鄢陵县| 班戈县| 营口市| 梨树县| 三台县| 宁津县| 乐陵市| 巴马| 正定县| 江孜县| 手机| 南通市| 临颍县| 霍林郭勒市| 横峰县| 新昌县| 临猗县| 诸城市| 左权县| 禄丰县| 九江市| 福贡县| 常德市| 五华县| 依安县| 上虞市| 平度市| 云和县| 建始县| 托里县| 怀柔区| 盐山县| 新绛县| 鄄城县| 尚志市|