標籤:靜態 源碼 java虛擬機器 管理 修改 反編譯工具 重啟 內容 緩衝
Java虛擬機器編譯機制:更改常量部分
最近一個Java項目中需要修改一個靜態常量的值,本地修改編譯以後調試正常,然後把對應的entity類的class檔案上傳到伺服器對應的目錄以後系統依舊我行我素,各種清除緩衝,各種重啟,最後查詢了相關資料,使用GUI反編譯工具反編譯查看編譯後源碼,終於找到問題所在:
*** 單純的修改靜態變數是沒用的,還要重新編譯所有引用靜態變數的類,不然不會生效的。
這裡就牽扯到Java虛擬機器編譯機制:在Java檔案中,指向編譯時間static final的靜態常量, 會被在運行時解析為一個局部的常量值(也就是說靜態常量在編譯後,成為了常量,而不是原先的代碼)。這對所有的基礎資料類型(就像int ,float等)和java.lang.String都適用。
例如:
public class Contant{public static final String STR = "alexgaoyh";//...... }
然後在某些邏輯程式碼片段裡使用了這些常量。這樣做可以便於管理常量,避免了大量的magic number/text,在修改常量內容時只需改這一個類就行了。
public class TestService {public void doSome() {//這裡應用了上一個類的靜態常量Contant.STRSystem.out.println(Contant.STR);} }
類TestService使用了Contant.STR這個常量,表面上是通過Contant類取得的這個值,實際上在TestService被編譯後,其代碼已經改變為
public class TestService {public void doSome() {//這裡把靜態常量Contant.STR直接編譯成為了一個常量"alexgaoyh"System.out.println("alexgaoyh");}}
也就是說 在所有使用常量的地方,都要重新進行編譯才會生效。
Java常量初始化後不會再去重新擷取