在這裏首先明確,靜態static關鍵字和jvm虛擬機常量池是兩個概念。java
只是static關鍵字修飾常量或者變量,會在類實例化以前就放在常量池中而已。dom
static關鍵字jvm
由static修飾的變量,常量和方法被稱爲靜態變量,常量和方法。測試
final關鍵字優化
由final修改的爲常量。由final和static共同修飾的爲靜態常量spa
以下:測試java中靜態常量和靜態變量區別的樣例,代表二者加載時的區別。code
StaticClass類中定義了靜態常量FIANL_VALUE和靜態變量VALUE,靜態代碼塊的打印語句表示類被加載:blog
public class StaticClass { static { System.out.println("StaticClass loading..."); } public static String VALUE = "static value loading"; public static final String FIANL_VALUE = "fianl value loading"; public static final int FINAL_VALUE_INT = new Random(66).nextInt(); }
StaticClassLoadTest類用於測試靜態變量的加載:內存
public class StaticClassLoadTest { public static void main(String[] args) { System.out.println("StaticClassLoadTest..."); printStaticVar(); } private static void printStaticVar() { // System.out.println(StaticClass.FINAL_VALUE_INT);//這個由於是隨機數,須要出發類加載 System.out.println(StaticClass.FIANL_VALUE); //這個由於是一個常量,不須要類加載就能獲得 System.out.println(StaticClass.VALUE); } }
輸出:虛擬機
輸出顯示在打印靜態常量時,StaticVar類並無被加載,在輸出靜態變量的前纔打印類加載信息。這代表類的未加載的狀況下也能引用其靜態常量信息,緣由是由於常量值存儲在JVM內存中的常量區中,在類不加載時便可訪問。
注:通過編譯優化,靜態常量 FIANL_VALUE 已經存到NotInit類自身常量池中,不會加載StaticClass
可是不能說全部的靜態經常使用訪問都不須要類的加載,這裏還要判斷這個常量是否屬於「編譯期常量」,即在編譯期便可肯定常量值。若是常量值必須在運行時才能肯定,如常量值是一個隨機值,也會引發類的加載,以下:
public static final int FINAL_VALUE_INT = new Random(66).nextInt();