所屬文集:ClassLoader串燒
編譯期常量
在編譯階段姓言,常量就被放到使用這個(gè)常量的方法的所在的類的常量池中
調(diào)用類瞬项,并沒有直接引用到定義常量的類,因此不會(huì)觸發(fā)定義常量的類 的初始化何荚。
因此兩者沒有了關(guān)聯(lián)囱淋,刪除定義常量的類的.class文件也不影響。
如:i'm strChild會(huì)被放到Test06的常量池中餐塘。
摘自https://www.cnblogs.com/grefr/p/6094871.html
以Java為例绎橘,static final int a = 1將是一個(gè)編譯時(shí)常量,編譯后的符號(hào)表中將找不到a唠倦,所有對a的引用都被替換成了1
對于這句話称鳞,要確認(rèn)如何查看符號(hào)表,怎么識(shí)別變成了1
案例1:
public class Test06 {
public static void main(String[] args) {
System.out.println(MyChild.strChild);
//只輸出:i'm strChild
//System.out.println(MyParent.strParent);
//只輸出:i'm parent
}
}
class MyChild extends MyParent {
public static final String strChild = "i'm strChild";
static {
System.out.println("this is MyChild static...");
}
}
class MyParent {
public static final String strParent ="i'm parent";
static {
System.out.println("this is MyParent static");
}
}
ldc命令參考
四稠鼻、ldc系列
該系列命令負(fù)責(zé)把數(shù)值常量或String常量值從常量池中推送至棧頂冈止。該命令后面需要給一個(gè)表示常量在常量池中位置(編號(hào))的參數(shù),
哪些常量是放在常量池呢候齿?比如:final static int id=32768;final static float double=6.5熙暴。
對于const系列命令和push系列命令操作范圍之外的數(shù)值類型常量,都放在常量池中.
另外慌盯,所有不是通過new創(chuàng)建的String都是放在常量池中的周霉。
指令碼 助記符 說明
0x12 ldc 將int, float或String型常量值從常量池中推送至棧頂
0x13 ldc_w 將int, float或String型常量值從常量池中推送至棧頂(寬索引)
0x14 ldc2_w 將long或double型常量值從常量池中推送至棧頂(寬索引)
運(yùn)行期常量
public class Test07 {
public static void main(String[] args) {
System.out.println(MyParent07.a);
System.out.println(MyParent07.str);
System.out.println(MyParent07.str);
}
}
class MyParent07{
public static final String str = UUID.randomUUID().toString();
public static final int a = 10;
static {
System.out.println("MyParent07 static executed");
}
}
查看輸出
[Loaded sun.nio.cs.US_ASCII$Decoder from C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar]
10//先輸出了10,之后才加載了MyParent07這個(gè)類
[Loaded MyParent07 from file:/C:/Users/rock/IdeaProjects/jvm-learn-07/jvmlearn07/target/classes/]
[Loaded java.util.UUID from C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar]
[Loaded java.util.UUID$Holder from C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar]
...
n多類加載信息忽略
...
MyParent07 static executed//靜態(tài)代碼塊執(zhí)行亚皂,只有首次加載才執(zhí)行初始化
19019819-1961-4e92-8816-8d2dab9df34c//輸出結(jié)果
19019819-1961-4e92-8816-8d2dab9df34c//輸出結(jié)果
[Loaded java.lang.Shutdown from C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar]
Process finished with exit code 0
MyParent07.str是運(yùn)行期常量俱箱;
不在調(diào)用者所在類的常量池中;
System.out.println(MyParent07.str);這樣的調(diào)用就是對MyParent07的主動(dòng)調(diào)用灭必,會(huì)引起類的初始化(初始化之前肯定要先加載)狞谱;