目前排名比較靠前的答案都回答得很淺顯易懂了。
我這里給你一個最可靠的理論依據(雖然比較晦澀)。
Java語言規范(JavaSE 1.8版本)章節3.10.5中對此作了規范,因此所有的Java語言編譯、運行時環境實現都必須依據此規范來實現。
里面有這么一句話Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.
大意是:凡是內容一樣的字符串常數,都要引用同一個字符串對象,換句話說就是內存地址相同。
原因是,其值為常量的字符串,都會通過String.intern()函數被限定為共享同一個對象。
具體也可以參考一下String.intern()函數的說明:String (Java Platform SE 8 )
上面的Java語言規范3.10.5里,還有一段代碼例子。
package testPackage;
class Test {
public static void main(String[] args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }
and the compilation unit:
package other;
public class Other { public static String hello = "Hello"; }
produces the output:
true true true true false true
從這段例子可以看出,凡是編譯期能推斷出值內容的字符串,都會在編譯時變成字符串常量,從而享有上面提到的共享對象的待遇。而運算中間插入了變量,讓編譯器認為只有運行時才能判斷其內容的字符串,則會在運行時產生新的對象。(倒數第二個輸出false的情況。)
計算機世界的東西就是這樣的,有人定下了規矩,大家就都得照規矩辦。畢竟整個計算機世界都是人造出來的,也就是這個帝國是由人類的規矩構建的,無論這個規矩是合理的還是不合理如鍵盤排布,一旦定下來也就不得不遵從了。
于是,就出現了你提問中的現象。說白了,做Java的人強制如此的。當然,從規矩產生的原因上說,這個規矩是有利于改善性能的。