老司機也暈車--java字串String暈車之旅
阿新 • • 發佈:2019-09-04
首先宣告,有暈車經歷的司機請自備藥物,String也可能讓你懷疑人生!
第一道 開胃菜
請聽題!第一道題:
String hello="hello world!"; String hello1=new String("hello world!"); System.out.println(hello==hello1); System.out.println(hello.equals(hello1));
提示: ==是比較兩個物件引用是否正好引用到了相同的物件。
那麼公佈答案吧
false
true
旁白:
- new String是新建物件,和字串常量物件不是同一個。
- equal是比較值
肯定不過癮吧,那就再來。
第二道 湯
String hello="hello world!"; String hello2="hello world!"; System.out.println(hello==hello2); System.out.println(hello.equals(hello2));
掃地僧看不下去了
true
true
旁邊:
兩個String型別的常量表達式,如果標明的是相同的字元序列,那麼它們就用相同的物件引用來表示。
第三道 副菜
String hello="hello world!"; String append="hello"+" world!"; System.out.println(hello==append); System.out.println(hello.equals(append));
那就公佈答案
truetrue
旁邊:
兩個String型別的常量表達式,如果標明的是相同的字元序列,那麼它們就用相同的物件引用來表示。
第四道 主菜
final String pig = "length: 10"; final String dog = "length: " + pig.length(); System.out.println(pig==dog); System.out.println(pig.equals(dog));
不敢說了,還是公佈答案吧
false
true
官方資料中有這麼一段話:
Strings concatenated from constant expressions (§15.28) are computed at compile time and then treated as if they were literals.
Strings computed by concatenation at run time are newly created and therefore distinct.
翻譯一下:
>通過常量表達式運算得到的字串是在編譯時計算得出的,並且之後會將其當作字串常量對待.
>在執行時通過連線運算得到的字串是新建立的,因此要區別對待。
看黑色重點標註。
第五道 蔬菜類菜餚
final String pig = "length: 10"; final String dog = ("length: " + pig.length()).intern(); System.out.println(pig==dog); System.out.println(pig.equals(dog));
先看答案吧
true
true
旁邊:
可以通過顯示的限定運算得到的字串為字串常量,String.intern方法可以"限定"
第六道 甜品
final String pig = "length: 10"; final String dog = "length: " + pig.length(); System.out. println("Animals are equal: "+ pig == dog); System.out.println("Animals are equal: "+ pig .equals(dog));
大家已經迫不及待了,先看答案
false
Animals are equal: true
如果你想一下操作符的優先順序就明白了,“+”優先順序高於“==”
第七道 咖啡、茶
看大家暈車嚴重,那就不出題目了
通過上面的教訓,在比較物件引用時,應該優先使用equals 方法而不是 == 操作符,除非需要比較的是物件的標識而不是物件的值。
參考資料
【1】https://docs.oracle.com/javase/specs/jls/se12/html/jls-3.html#jls-3.10.5
【2】https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.