自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

【JVM類加載】類的加載,連接與初始化

開發(fā) 后端
類的加載指的是將類的.Class文件中的二進(jìn)制數(shù)據(jù)讀入到內(nèi)存中,將其放在運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū)內(nèi),然后在內(nèi)存中創(chuàng)建一個(gè)Java.lang.Class對(duì)象(規(guī)范化并未說明Class對(duì)象位于哪里,HotSpot虛擬機(jī)將其放在方法區(qū)中)用來封裝類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)。

類加載

  • 在java代碼中,類型的加載,連接與初始化過程都是在程序運(yùn)行期間完成的(類class文件信息在編譯期間已經(jīng)確定好)。
  • 提供了更大的靈活性,增加了更多的可能性。

類加載器

java虛擬機(jī)與程序的生命周期:
在如下幾種情況下,java虛擬機(jī)將結(jié)束生命周期:

  • 執(zhí)行System.exit()方法
  • 程序正常執(zhí)行結(jié)束
  • 程序在執(zhí)行過程中遇到了異?;蝈e(cuò)誤向上拋出異常拋到main入口程序終止
  • 由于操作系統(tǒng)出現(xiàn)錯(cuò)誤而導(dǎo)致java虛擬機(jī)進(jìn)程終止

類的加載流程三部分

加載:查找并加載類的二進(jìn)制數(shù)據(jù)

連接 :

驗(yàn)證:確保被加載的類的正確性(字節(jié)碼是否符合JVM的規(guī)范)

準(zhǔn)備:為類的靜態(tài)變量分配內(nèi)存,并將其初始化值設(shè)置為默認(rèn)值

如 public static int a = 1; 先設(shè)置為默認(rèn)值0.

解析: 把類中的符號(hào)引用轉(zhuǎn)換成直接引用

初始化:為類的靜態(tài)變量賦予正確的初始值未開發(fā)人員定義的靜態(tài)變量賦予真實(shí)的值。

解析過程

類的使用與卸載

  • 使用
  • 卸載

類的加載,連接與初始化

java程序?qū)︻惖氖褂梅绞娇煞譃閮煞N:

  • 主動(dòng)使用

所有的java虛擬機(jī)實(shí)現(xiàn)必須在每個(gè)類或接口被java程序“首次主動(dòng)使用”時(shí)才初始化他們。

  • 被動(dòng)使用

類的加載,連接,初始化。

初始化和實(shí)例化的區(qū)別?

初始化只是類加載,只執(zhí)行一次,即只有有一個(gè)類對(duì)象(注意不是實(shí)例對(duì)象),無論你以后怎么個(gè)new法,新new的都是實(shí)例對(duì)象。

Object o = null; 或者 Objects o;// 這個(gè)叫初始化,只在棧內(nèi)存中存在,并沒有獲取到實(shí)際的引用o = new Object(); // 這是實(shí)例化()。

spring bean的初始化(區(qū)別類的初始化實(shí)例化)。

spring bean的初始化,是對(duì)實(shí)例化出來的對(duì)象進(jìn)行填充初始化。

實(shí)例化(Instantiation)—-實(shí)例化的過程是一個(gè)創(chuàng)建Bean的過程,即調(diào)用Bean的構(gòu)造函數(shù),單例的Bean放入單例池中。

初始化(Initialization)—-初始化的過程是一個(gè)賦值的過程,即調(diào)用類對(duì)象的setter,設(shè)置類對(duì)象的屬性 區(qū)別類加載 spring bean實(shí)例在前初始化在后。

主動(dòng)使用(七種)

  • 創(chuàng)建實(shí)例類
  • 訪問某個(gè)類或接口的靜態(tài)變量,或者對(duì)該靜態(tài)變量賦值
  • 調(diào)用類的靜態(tài)方法
  • 反射
  • 初始化一個(gè)類的子類
  • java虛擬機(jī)啟啟動(dòng)時(shí)被表明為啟動(dòng)類的類
  • JDK1.7開始提供的動(dòng)態(tài)語言支持:java.lang.invoke.MethodHandle實(shí)例的解析結(jié)果REF_getStitac,REF_putStatic,REF_invokeStatic句柄對(duì)應(yīng)的類沒有初始化則初始化

助記符:

助記符

  • getstatic 初始化時(shí)訪問靜態(tài)變量。
  • putstatic 初始化時(shí)給靜態(tài)方法賦值。
  • invokestatic 初始化時(shí)調(diào)用靜態(tài)方法。
/**
 * 1.System.out.println(MyParent1.str)對(duì)于靜態(tài)字段來說,只有定義了該字段的類才會(huì)被初始化
 * 2.System.out.println(MyChild1.str2)對(duì)于子類被初始化,要求其父類全部被初始化完畢
 */
public class Test01 {

    public static void main(String[] args) {
        System.out.println(MyParent1.str); //調(diào)用父類的靜態(tài)變量時(shí) 子類沒有被初始化
//        System.out.println(MyChild1.str2); //全部初始化
    }

}

class MyParent1{

    public static String str = "hello word";

    static {
        System.out.println("MyParent1 static block");
    }

}

class MyChild1 extends MyParent1{

    public static String str2 = "welecome";

    static {
        System.out.println("MyChild1 static block");
    }
}

除了以上7種情況,其他使用java類的方式都被看做是對(duì)類的被動(dòng)使用,都不會(huì)導(dǎo)致類的初始化。

類的加載

類的加載指的是將類的.class文件中的二進(jìn)制數(shù)據(jù)讀入到內(nèi)存中,將其放在運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū)內(nèi),然后在內(nèi)存中創(chuàng)建一個(gè)java.lang.Class對(duì)象(規(guī)范化并未說明Class對(duì)象位于哪里,HotSpot虛擬機(jī)將其放在方法區(qū)中)用來封裝類在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)。

記載.class文件的方式

  • 從本地系統(tǒng)中直接加載(自己編寫的)。
  • 通過網(wǎng)絡(luò)載.class文件。
  • 從zip.jar等歸檔文件中加載.class文件(maven)。
  • 將源文件動(dòng)態(tài)編譯為.class文件(動(dòng)態(tài)代理,cglib)。
  • 從專有的數(shù)據(jù)庫(kù)中提取.class文件。
//常量在編譯階段會(huì)存入到調(diào)用這個(gè)常量的方法所在的類的常量池中
//本質(zhì)上,調(diào)用類并沒有直接引用到定義常量的類,因此并不會(huì)觸發(fā) 定義常量的類的初始化
// 注意:這里指的是將常量存放到了Test2的常量池中,之后Test2與MyParent2就沒有任何關(guān)系了
// 甚至,我們可以將MyParent2的class文件刪除

/**
 * javap -c  查看助記符
 * ldc標(biāo)識(shí)將int,float或是String類型的常量值從常量池中推送到棧頂
 * bipush標(biāo)識(shí)將單字節(jié)(-128 - 127)的常量值推送至棧頂
 * sipush表示將一個(gè)短整型常量值(-32768 - 32767)推送至棧頂
 * iconst_1表示將int類型1推送至棧頂(iconst_1 ~ iconst_5)
 * iconst_m1表示將int類型-1推送至棧頂
 */
public class Test2 {

    public static void main(String[] args) {
        System.out.println(MyParent2.i);
    }
}

class MyParent2{

    public static final String str = "hello world";

    public static final int i = 128;

    static {
        System.out.println("Myparent2 static block");
    }

}
/*
    當(dāng)一個(gè)常量的值并非編譯期間可以確定的,那么其值就不會(huì)被放到調(diào)用類的常量池當(dāng)中,
    這時(shí)在程序運(yùn)行時(shí),會(huì)導(dǎo)致主動(dòng)使用這個(gè)常量所在的類,顯然會(huì)導(dǎo)致這個(gè)類被初始化。
 */
public class Test3 {
    public static void main(String[] args) {
        System.out.println(MyParent3.STRING);
    }
}

class MyParent3{
    public static final String STRING = UUID.randomUUID().toString();

    static {
        System.out.println("MyParent3 static code");
    }
}

接口:

/*
    當(dāng)一個(gè)接口在初始化時(shí),并不要求其父接口都完成了初始化
    只有在真正使用到父接口的時(shí)候 (引用接口中定義的常量時(shí)),才會(huì)初始化
 */
public class Test5 {

    public static void main(String[] args) {
        System.out.println(MyChild5.b);
    }
}

interface MyParcnt5{

    public static final int a = 5;
}

interface MyChild5 extends MyParcnt5{

    public static int b = new Random().nextInt(4);
}
public class Test6 {

    public static void main(String[] args) {
        Singleton singleton = Singleton.getSingleton();

        System.out.println("i=" + Singleton.i);
        System.out.println("b=" + Singleton.b);
    }
}
//當(dāng)類加載時(shí) 程序是自上而下執(zhí)行的
// 靜態(tài)變量:類變量,類的所有實(shí)例都共享,我們只需知道,在方法區(qū)有個(gè)靜態(tài)區(qū),靜態(tài)區(qū)專門存放靜態(tài)變量和靜態(tài)塊。
class Singleton {

    public static int i;


    public static Singleton singleton = new Singleton();//又初始化

    private Singleton() {
        i++;
        b++;//準(zhǔn)備階段的意義
        //此時(shí) i和b都被賦值為1
        System.out.println(i);
        System.out.println(b);
    }
    //此時(shí) b= 1 又被賦值為0
    public static int b = 0;

    public static Singleton getSingleton() {
        return singleton;
    }
}
/*
1
1
i=1
b=0
 */

注意:一定要將初始化和實(shí)例化分開 初始化時(shí)將一個(gè)類里的靜態(tài)變量附上正確的值(程序員需要賦的值) 一個(gè).clas類只初始化一次,實(shí)例化他可以多次創(chuàng)建沒new一次就是一個(gè)實(shí)例化 (初始化不一定實(shí)例化實(shí)例化一定初始化了)。

靜態(tài)變量初始化

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2024-03-12 07:44:53

JVM雙親委托機(jī)制類加載器

2011-07-22 17:46:43

java

2020-11-02 07:02:10

加載鏈接初始化

2011-03-17 09:58:43

Java虛擬機(jī)JVM

2012-05-23 12:46:53

JavaJava類

2023-10-31 16:00:51

類加載機(jī)制Java

2024-12-02 09:01:23

Java虛擬機(jī)內(nèi)存

2017-09-20 08:07:32

java加載機(jī)制

2024-04-09 08:41:41

JVM類加載Java

2021-04-29 11:18:14

JVM加載機(jī)制

2017-03-08 10:30:43

JVMJava加載機(jī)制

2020-10-26 11:20:04

jvm類加載Java

2023-08-02 08:38:27

JVM加載機(jī)制

2024-03-28 12:32:18

JVM類加載構(gòu)造器

2012-02-28 10:04:09

Java

2021-07-05 06:51:43

Java機(jī)制類加載器

2011-07-12 10:24:17

類加載反射

2012-02-09 10:31:17

Java

2020-05-12 22:24:44

JVM系統(tǒng)加載器

2022-10-08 08:34:34

JVM加載機(jī)制代碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)