當執行以下代碼的時候會發生什麼呢
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。