2011-01-20 143 views
3

比較兩個字符串時,我被教導不應該使用邏輯運算符(==)。我們應該使用String.equals(String)進行比較。但是,我發現下面的代碼符合並使用最新的JDK(1.6_23)打印「Hello Friend」。我試着四處搜尋,找不到任何參考。從何時發生?在Java中與邏輯運算符進行字符串比較

public class StringComp{ 
public static void main(String args[]){ 
     String s = "hello"; 
     if(s=="hello"){ 
       System.out.println("Hello Friend"); 
     }else{ 
       System.out.println("No Hello"); 
     } 
    } 
} 
+2

http://stackoverflow.com/questions/767372/java-string-equals-versus – 2011-01-20 08:43:24

+1

另請參閱http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java (接受的答案是指實習) – finnw 2011-01-20 08:53:50

+1

我不認爲這是一個騙局。這個問題是問「爲什麼它有時會工作」而不是「爲什麼它通常不起作用」 – finnw 2011-01-20 08:56:09

回答

10

您不應該使用==,因爲它做了其他的事情,那麼你認爲。

在這種情況下,「hello」被保存(在字符串實習中讀取),所以與您的結果相同的是「巧合」。

==檢查兩件事情是完全相同的事情,而不是如果他們有相同的內容。這是一個非常大的差異,一些偶然的(雖然可以解釋的)「錯誤的possitives」沒有理由使用這種方法。

只需使用等於字符串比較。

從這個網站的例子: http://blog.enrii.com/2006/03/15/java-string-equality-common-mistake/

String a = new String ("a"); 
String b = new String ("a"); 
System.out.println (a == b); 

返回false,而下面的代碼返回true。

String a = new String ("a"); 
String b = new String ("a"); 
System.out.println (a.equals(b)); 
2

==操作者用於檢查如果兩者都同時.equals比較的值,以相同的字符串對象的引用。

2

它適用於您的情況(並且AFAIK它一直在像以前的JVM一樣工作),因爲s引用字符串文字"hello"。用文字初始化的字符串引用指的是文字(它是背景中的全局對象),而不是單獨創建的新對象。正如其他人所提到的,這個術語是實習。因此,您示例中的s"hello"指的是相同的物理對象。考慮

String s1 = "hello"; 
String s2 = "hello"; 
String s3 = "hello"; 

所有這些字符串的指代相同的物理對象,從而「==」之間,或其中的任何和"hello"返回true任何對這些進行比較。

然而

String s4 = new String ("hello"); 

創建一個新對象,因此s4 == "hello"產生false

4

這個魔術叫做實習

爪哇實習生字符串文字等有其評估爲真高概率:

String a = "hello";  // "hello" is assigned *and* interned 
String b = "hello";  // b gets a reference to the interned literal 
if (a == b) 
    System.out.println("internd."); 

String c = "hello" + Math.abs(1.0); // result String is not interned 
String d = "hello" + Math.abs(1.0); // result String is not interned 
System.out.println(c==d);    // prints "false" 

c = c.intern(); 
System.out.println(c==d);    // prints "false" 

d = d.intern(); 
System.out.println(c==d);    // prints "true" 
-1

==比較對象引用,等於()比較字符串的值。

在你的情況你分配兩個值爲「你好」的字符串對象,然後將它們與==比較。編譯器可能會決定優化和使用相同的對象引用,從而得到如你所得到的真實結果。然而這不是保證的行爲 - 使用equals()進行值比較要安全得多。

0

「Java虛擬機維護一個內部字符串(唯一字符串池)引用的內部列表,以避免堆內存中出現重複的字符串對象。每當JVM從類文件加載字符串字符串並執行時,它會檢查該字符串是否存在在內部列表中,如果它已經存在於列表中,那麼它不會創建一個新的String,它會使用對現有String對象的引用。JVM在內部爲String類型進行這種類型的檢查,通過'new'關鍵字創建你可以顯式強制JVM對String對象進行這種類型的檢查,這是通過使用String.intern()方法通過'new'關鍵字創建的,這迫使JVM檢查內部列表並使用現有的String對象,如果它已經存在。

因此得出的結論是,JVM在內部爲String字面值維護唯一的String對象。程序員不需要關心字符串文字,但是他們應該爲使用'new'關鍵字創建的String對象而煩惱,他們應該使用intern()方法來避免堆內存中重複的String對象,從而提高Java性能。請參閱以下部分以獲取更多信息「

參考:PreciseJava.com - Optimization techniques in Strings and StringBuffer (How the JVM works with Strings)

0

==比較對象引用

您可以通過觀察下面的代碼輸出明白:

public class StringComp{ 
    public static void main(String args[]){ 
     String s = new String("hello"); 
     if(s=="hello"){ 
       System.out.println("Hello Friend"); 
     }else{ 
       System.out.println("No Hello"); 
     } 
    } 
} 

這程序將打印No hello

因爲在此代碼中,vari能夠s引用新的字符串對象,它反過來引用字符串池中的字符串字符串「hello」。