最近一個Java項目中須要修改一個靜態常量的值,本地修改編譯之後調試正常,而後把對應的entity類的class文件上傳到服務器對應的目錄之後系統依舊我行我素,各類清除緩存,各類重啓,最後查詢了相關資料,使用GUI反編譯工具反編譯查看編譯後源碼,終於找到問題所在:html
單純的修改靜態變量是沒用的,還要從新編譯全部引用靜態變量的類,否則不會生效的。java
這裏就牽扯到Java虛擬機編譯機制:在Java文件中,指向編譯時static final的靜態常量, 會被在運行時解析爲一個局部的常量值(也就是說靜態常量在編譯後,成爲了常量,而不是原先的代碼)。這對全部的基礎數據類型(就像int ,float等)和java.lang.String都適用。緩存
請看下面一個實例:程序中使用的各類常量用一個類Contant.java來統一管理。服務器
而後在某些邏輯代碼段裏使用了這些常量。這樣作能夠便於管理常量,避免了大量的magic number/text,在修改常量內容時只需改這一個類就好了。工具
類SomeService使用了Contant.STR這個常量,表面上是經過Contant類取得的這個值,實際上在SomeService被編譯後,其代碼已經改變spa
這裏面根本沒有Contant類什麼事,因此你即便修改了Contant類的相關常量,令STR = 「www.csyor.com」,SomeService依然會打印 「csyor.com」 ,由於SomeService的代碼沒有任何修改,在增量編譯的狀況下,它的class文件不會被從新編譯。調試
那麼說到這裏可能會有人問:那爲何你在本地調試的好用呢?code
主要是由於本地通常使用的IDE(集成開發環境)是能夠自動編譯的,而咱們上傳到服務器的時候通常只是上傳本身更改過的java文件編譯後的class文件(也就是包含靜態常量的class),至於引用這個靜態常量的其餘類由於沒有改動過因此不會上傳,就出現了本地調試不會出現問題,可是在服務器上沒有效果的狀況。htm
明白了上面這些,我已經解決了問題,你應該也能知道怎麼去解決了吧!固然,無論是更換什麼class文件,必定須要重啓中間件容器。
靜態常量,咱們使用時必定要慎重。一旦有修改就須要將整個項目從新編譯替換。中間件