java編譯優化-常量引用替換
阿新 • • 發佈:2021-08-09
常量引用替換
這個絕對是個坑,有時候為了節省時間,圖方便,會在伺服器直接替換新修改的配置類的class檔案。但是往往會出現替換完以後,伺服器的war包實際沒有生效。這就是因為java編譯的自動優化發生了常量引用替換。
當Java編譯器編譯原始碼時,如果發現某處程式碼引用了「常量」(同時使用static
和final
兩個關鍵字來修飾),且該常量為字面值形式的原始資料型別或字串,Java編譯器會將此處的常量引用優化為常量值的「內聯」(inline)。
舉個例子:
public class Const { /** 請求第三方平臺所需的 APP_ID */ public static finalString APP_ID = "theAppId"; /** 請求第三方平臺所需的 APP_KEY */ public static final String APP_KEY = "thePassword"; }
public class ThirdPartyClient { public void postRequest(String args) { // Const.APP_ID 的引用 被替換成了該常量在編譯時的字串字面值 // Const.APP_KEY 的引用 被替換成了該常量在編譯時的字串字面值 String text = "theAppId" + "thePassword" + args;// handle the text // …… } }
在Java中,常量在初始化賦值後是不能再被改變的,因此Java編譯器就會針對常量進行優化,從而在執行時避免變數引用的呼叫開銷。
大家瞭解了Java編譯器的這個優化特性之後,自然也就能夠輕鬆避免這樣的問題。
小結
- Java編譯器會在編譯原始碼時,也會進行優化,會將程式碼中的常量引用替換為對應的字面值。
- 並不是所有的常量引用都會被替換,該常量必須是原始資料型別或字串型別,常量的值必須是字面值(例如:
1
、true
、"Hello"
)或在編譯期間能夠直接計算出結果的常量表達式(例如:2 * 2
,5 + 1
,"Hello" + "World"
注意
- 在應用部署的過程中,儘量不要通過類似的方式來修改配置引數!這種重複的必要性操作是很容易疏忽的,一旦疏忽,就可能給生產環境帶來重大損失。我們應該編寫程式程式碼或使用第三方工具,確保依賴於執行環境的引數配置能夠自動化智慧化的切換,而無需在每次部署時都提心吊膽。
- 上面示例程式碼中的"theAppId" + "thePassword"實際上也會被 Java 編譯器優化合併為一個字串字面值"theAppIdthePassword"。
參考文章:https://codeplayer.vip/p/j7thg