比較String用什麼好?

String對象真的可以用==比較嗎?

前一陣子用findbug插件尋找bug,發現了一個很奇怪的bug,內容如下:

subTargetNode.addText( (null == subTarget || "" == subTarget.trim() ) ? "_blank" : subTarget );
subTargetNode.addText( (null == subTarget || "" == subTarget.trim() ) ? "_blank" : subTarget );
[ES] Comparison of String objects using == or != [ES_COMPARING_STRINGS_WITH_EQ]
This code compares java.lang.String objects for reference equality using the == or != operators. Unless both strings are either constants in a source file, or have been interned using the String.intern() method, the same string value may be represented by two different String objects. Consider using the equals(Object) method instead.

 

  String不是immutable的類嗎?而且還有String Pool,在JVM中相同內容的String對象不是隻有一個嗎?爲什麼不可以用==比較相等?東東在網上搜索了一篇文章又查了一下Java Language Specification,有點明白了,
  那篇文章如下:
  看例子:例子A:

String str1 = "java";
String str2 = "java";
System.out.print(str1==str2);

 

  地球上有點Java基礎的人都知道會輸出false,因爲==比較的是引用,equals比較的是內容。不是我忽悠大家,你們可以在自己的機子上運行一 下,結果是true!原因很簡單,String對象被放進常量池裏了,再次出現“java”字符串的時候,JVM很興奮地把str2的引用也指向了 “java”對象,它認爲自己節省了內存開銷。不難理解吧 呵呵
  例子B:

String str1 = new String("java");
String str2 = new String("java");
System.out.print(str1==str2);

 

  看過上例的都學聰明瞭,這次肯定會輸出true!很不幸,JVM並沒有這麼做,結果是false。原因很簡單,例子A中那種聲明的方式確實是在 String常量池創建“java”對象,但是一旦看到new關鍵字,JVM會在堆中爲String分配空間。兩者聲明方式貌合神離,這也是我把“如何創 建字符串對象”放到後面來講的原因。大家要沉住氣,還有一個例子。
  例子C:

String str1 = "java";
String str2 = "blog";
String s = str1+str2;
System.out.print(s=="javablog");

 

  再看這個例子,很多同志不敢妄言是true還是false了吧。愛玩腦筋急轉彎的人會說是false吧……恭喜你,你會搶答了!把那個“吧”字去掉你就完 全正確。原因很簡單,JVM確實會對型如String str1 = "java"; 的String對象放在字符串常量池裏,但是它是在編譯時刻那麼做的,而String s = str1+str2; 是在運行時刻才能知道(我們當然一眼就看穿了,可是Java必須在運行時才知道的,人腦和電腦的結構不同),也就是說str1+str2是在堆裏創建的, s引用當然不可能指向字符串常量池裏的對象。沒崩潰的人繼續看例子D。
  例子D:

String s1 = "java";
String s2 = new String("java");
System.out.print(s1.intern()==s2.intern()); 

 

  intern()是什麼東東?反正結果是true。如果沒用過這個方法,而且訓練有素的程序員會去看JDK文檔了。簡單點說就是用intern()方法就 可以用“==”比較字符串的內容了。在我看到intern()方法到底有什麼用之前,我認爲它太多餘了。其實我寫的這一條也很多餘,intern()方法 還存在諸多的問題,如效率、實現上的不統一……
  例子E:

 

String str1 = "java";
String str2 = new String("java");
System.out.print(str1.equals(str2));

 

無論在常量池還是堆中的對象,用equals()方法比較的就是內容,就這麼簡單!

 

字符串的比較用equals.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章