學習JVM的第二天

當執行以下代碼的時候會發生什麼呢

package com.example.demo.test;

import java.util.UUID;

public class MyTest2 {

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

class MyParent2{
    public static final String str= UUID.randomUUID().toString();
    static {
        System.out.println("this is MyParent2");
    }
}

執行結束後,它的結果居然是

this is MyParent2
948f8c54-59ac-4151-88c0-df6d4cc2ee167

得出結論:當一個常量的值並非編譯期間可以確定的,那麼其值就不會被放到調用類的常量池中,這時在程序運行時會導致主動使用這個常量所在類,顯然會導致這個類被初始化。

其實還有一個疑問,如果我創建的是這個類的數組,那麼它的static代碼塊會不會被執行呢

package com.example.demo.test;


public class MyTest3 {

    public static  void main( String[] args){
        MyParent3[] myParent3s=new MyParent3[3];
        System.out.println(myParent3s.getClass());
    }

}


class MyParent3 {
    static {
        System.out.println("this is MyParent3");
    }
}

查看結果

class [Lcom.example.demo.test.MyParent3;

也就是說沒有被初始化,這是爲啥,我通過反編譯之後查看結果發現助記符anewarray

anewarray:專門給對象創建數組而去使用的,給對象創建新數組還有newarray

 

通過執行查看結果,然後再去反編譯

發現反編譯之後的int類型數組是newarray助記符

當我new一個對象的時候,執行完成之後,再去反編譯發現

new這個助記符就是在創建對象實例,也就是符合主動使用的要求,所以便會被初始化

 

總結:只有在對象主動使用的時候,該類文件纔會被初始化,其他情況都是屬於被動使用,並不會去初始化對象。那麼對於對象數組一說,其實是在內存中開闢一塊內存空間,用來存放該類型的固定長度的數組集。

補充:關於使用javap反編譯的可以查看   https://www.jianshu.com/p/6a8997560b05

           更多參考java中的助記符,請看:package com.sun.org.apache.bcel.internal 包下的 Constants。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章