首先來比較兩段代碼所產(chǎn)生的中間代碼:
public class AppConfig {
public static final boolean debug = true;
}
public class DebugCode {
public static void main(String[] args) {
if(AppConfig.debug) {
System.out.println("Some debug information");
}
}
}
DebugCode的中間代碼(部分):
public class org.levin.insidejvm.miscs.DebugCode {
public static void main(java.lang.String[] args);
0 getstatic java.lang.System.out : java.io.PrintStream [16]
3 ldc <String "Some debug information"> [22]
5 invokevirtual java.io.PrintStream.println(java.lang.String) : void [24]
8 return
}
public class AppConfig {
public static final boolean debug = false;
}
public class ReleaseCode {
public static void main(String[] args) {
if(AppConfig.debug) {
System.out.println("Some debug information");
}
}
}
ReleaseCode中間代碼(部分):
public class org.levin.insidejvm.miscs.ReleaseCode {
public static void main(java.lang.String[] args);
0 return
}
在上面的代碼中,很明顯DebugCode和ReleaseCode中的代碼是一樣的,只是AppConfig.debug的值不一樣而已,卻產(chǎn)生了不同的中間代碼,即編譯器在AppConfig.debug為false的時候直接忽略了if中的語句。利用這個特性,我們就可以根據(jù)配置來實現(xiàn)條件編譯,從而實現(xiàn)不同的條件產(chǎn)生不同的中間代碼而不只是不同的運行結(jié)果。
然而在這里為什么會出現(xiàn)這樣的行為呢?
這是因為編譯器對final修飾的基本類型和String類型的變量,在編譯時解析為一個本地拷貝,這樣拷貝導致編譯器在編譯的時候明確的知道ReleaseCode的那一段if語句是不會被執(zhí)行的,因而可以對其做優(yōu)化。而這種替換的結(jié)果也使得用final修飾的int變量可以出現(xiàn)在switch-case語句中。
這種方式的缺陷
這種方式的缺陷在于要現(xiàn)實該機制的條件編譯,在改變AppConfig.debug中的值時,需要同時對AppConfig類和ReleaseCode類進行編譯(即不能只編譯AppConfig類)。
參考:《深入Java虛擬機(第二版)》第八章
2010-09-22
posted on 2011-07-20 00:23
DLevin 閱讀(1753)
評論(0) 編輯 收藏 所屬分類:
Core Java