關於字符串比較用equals還是用==,總結一下.
字符串為對象:
1."=="
所有"對象變量"用==作比較時比的是兩個對象在堆中的引用.
2."equals()"
所有對象的equals方法繼承自Object類的方法,而String重寫了equals方法的比較算法,它比較的是字符串的內容,即在堆中的了符序列
3.特點
字符串是一種比較特殊的對象,這里的特殊指的是在運行期間,它的賦值直接改變引用(當然,任何對象的賦值都是直接改變的引用,只不過字符串這種東西往往讓人容易理解為它是在原來的基礎上操作的,尤其是+=這類操作),而不是在原來所引用的內存塊中做修改.(因此有了StringBuffer類的出現)
結論:
1.
String s1 = "hello";
String s2 = "hello";
System.out.println(s1.equals(s2)); //true
System.out.println(s1 == s2); //true
按照上面的說法,第一個true不難理解.
而第2個之所以也為true是因為,java編譯器用的類似於C語言中的"文字池機制",即在源代碼中所有的字符串常量聲明全部放在一塊內存區域,因此當一個字符串聲明時賦值的是一個字符串常量,那么如果"文字池"中有這個字符串常量,編譯器將直接把它的引用賦值給這個變量.
因此在用==來比較s1和s2時,將會得到true.
2.
String s1 = "hello";
String s2 = "hello";
s1 = s1 + "a";
s2 = s2 + "a";
System.out.println(s1.equals(s2)); //true
System.out.println(s1 == s2); //false
第3,4行的賦值操作在運行期間執行,根據上面的知識點3:兩個變量的引用將會發生改變.因此這時用==相比時將會得到false;
(在運行期間所得到的字符串內容,將不會放到所謂的"文字池"之中,然后如果有相同內容的變量引用相同內容,這樣作的話需要每次字符串改變時需要檢查它的內容,並再在文字池中查找看是否有相同內容的常量,太過浪費效率.)
("文字池機制"也許也是為什么字符串對象在作更改時,直接改變引用的一個原因,因為如果直接對引用的內存塊作操作的話,另一個指向相同引用的字符串變量將也會發什么改變,發生邏輯混淆)
3.
代碼略.
當字符串對象從不同地方(字符串常量;本地資源文件讀取;網絡傳輸:如表單提交;等等)獲得時:除了是編譯期間用相同常量賦值的字符串變量的引用相同外,其它的全部是新的引用.因此,與這種變量直接用==相比時將得到false,即使內容相同
應用結論:
1.如果是單純的比較字符串內容的話:用equals()
2.如果確實是要比較兩個變量的引用的話:用==