通過位元組碼,你才能真的讀懂String,

  • 2019 年 10 月 29 日
  • 筆記

最近在突然想到了 String 字元串拼接問題,於是做了一個 demo 測試了一下,到底 String 類型的字元串在拼接的時候,哪種情況下會走會走 StringBulider 進行字元串拼接,而哪種情況編譯器會對程式碼進行優化?話不多說,先看 demo

一. 問題

案例 1

測試程式碼 1.png

可以發現,str == str2 的結果為 false,那麼我們在看看下一個例子。

案例 2

測試程式碼 2.png

這時候,兩個字元串對比的結果為 true。

二. 探究問題

這時候,疑問就來了,為什麼結果會不一致呢?*利用在 cmd 窗口輸入 javap -c TestDemo.class 命令,對位元組碼文件進行反編譯,發現了問題所在?*

測試程式碼 1cmd.png

可以看到在案例 1 中,java 程式碼底層走了 StringBuilder,進行字元串拼接,然後調用了 StringBuilder 的 toString 方法。

測試程式碼 2cmd.png

而案例 2 中,對 class 文件進行反編譯,發現程式碼出現了一點變化,並沒有走 StringBuilder 進行字元串拼接。

三. 總結

1、案例 1 中,通過變數和字元串拼接,java 是需要先到記憶體找變數對應的值,才能進行完成字元串拼接的工作,這種方式 java 編譯器沒法優化,只能走 StringBuilder 進行拼接字元串,然後調用 toString 方法,當然返回的結果和常量池中的 111 這個字元串的記憶體地址是不一樣的,因此結果為 false。

2、案例 2 中,直接在表達式里寫值,java 不用根據變數去記憶體里找對應的值,可以在編譯的時候直接對這個表達式進行優化,優化後的表達式從 "111" + ""直接變成了"111" ,兩個 String 類型的變數都指向了常量池的 111 字元串,因此結果為 true;

Tags: