2014-01-18 23 views
4

訪問String Constant Pool Java常量池中兩個字符串的引用id

public class StringLiterals { 
    public static void main(String[] args) { 
     String s1="This is "; 
     s1=s1+"my book"; 
     String s2="This is my book"; 
     System.out.println(s1==s2); 

    } 
} 

O/P:假

期待O/P:真

+4

'「這是」 +「我的書」'是首先'「這ismy書」'缺乏空間的因此不管你如何比較它都不相等。 – zapl

+0

「這是」+「我的書」也是假的。 –

+0

提供鏈接後,你應該寫一個真正的問題來清除所有這些已經造成的混淆。 – csmckelvey

回答

3

您的代碼編譯成

public static void main(java.lang.String[]); 
    Code: 
     0: ldc   #16     // String This is 
     2: astore_1  
     3: new   #18     // class java/lang/StringBuilder 
     6: dup   
     7: aload_1  
     8: invokestatic #20     // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 
     11: invokespecial #26     // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
     14: ldc   #29     // String my book 
     16: invokevirtual #31     // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
     19: invokevirtual #35     // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
     22: astore_1  
     23: ldc   #39     // String This is my book 
     25: astore_2  
     26: getstatic  #41     // Field java/lang/System.out:Ljava/io/PrintStream; 
     29: aload_1  
     30: aload_2  
     31: if_acmpne  38 
     34: iconst_1  
     35: goto   39 
     38: iconst_0  
     39: invokevirtual #47     // Method java/io/PrintStream.println:(Z)V 
     42: return 

這相當於

public static void main(String[] args) { 
    StringBuilder sb = new StringBuilder("This is "); 
    sb.append("my book"); 
    String s1 = sb.toString(); 
    String s2 = "This is my book"; 
    System.out.println(s1 == s2); 
} 

因爲

s1=s1+"my book"; 

不是一個常量表達式 - 你正在閱讀一個變量的值,編譯器會假設你可以在此期間改變它。如果你想

由常量表達式計算的字符串(§15.28)在編譯時計算出來,然後視爲它們是文字。 JLS (§3.10.5)

適用你就必須更改您的代碼

public static void main(String[] args) { 
    String s1 = "This is " + "my book"; 
    String s2 = "This is my book"; 
    System.out.println(s1 == s2); 
} 

public static void main(String[] args) { 
    final String s1a = "This is "; 
    final String s1b = "my book"; 
    String s1 = s1a + s1b; 

    String s2 = "This is my book"; 
    System.out.println(s1 == s2); 
} 

,現在你保證,它的作品。第二個例子編譯成

public static void main(java.lang.String[]); 
    Code: 
     0: ldc   #16     // String This is 
     2: astore_1  
     3: ldc   #18     // String my book 
     5: astore_2  
     6: ldc   #20     // String This is my book 
     8: astore_3  
     9: ldc   #20     // String This is my book 
     11: astore  4 
     13: getstatic  #22     // Field java/lang/System.out:Ljava/io/PrintStream; 
     16: aload_3  
     17: aload   4 
     19: if_acmpne  26 
     22: iconst_1  
     23: goto   27 
     26: iconst_0  
     27: invokevirtual #28     // Method java/io/PrintStream.println:(Z)V 
     30: return  

,正如你所看到的負載2倍字符串#20

0

不能使用==兩個字符串比較,因爲==操作符斷言S1和S2指向相同的內存位置,而不是內容相同。要比較兩個字符串的內容以查看它們是否包含相同的內容,請使用String的.equals()方法。另外,您需要在s1=s1+產品線上留出額外的空間。

代碼:

{ 
public class StringLiterals { 
public static void main(String[] args) { 
    String s1="This is"; 
    s1=s1+" my book"; 
    String s2="This is my book"; 
    System.out.println(s1.equals(s2)); 

    } 
} 

如果你想使用==,您將不得不使用這樣的:

public class StringLiterals 
{ 
    public static void main(String[] args) 
    { 
    String s1 = "This is my book"; 
    String s2 = s1; 
    System.out.println(s1 == s2); 
    } 
} 

因爲字符串的對象,他們的行爲==不同於整數,字符和其他原語。

+2

他期待他們在同一個內存位置 –

+0

編譯器將連接字符串文字和intern然後它就可以工作。 http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5 – zapl

+0

我修改了我的答案,顯示了同時使用.equals()和= =,其中兩個都返回true。 –

6

也許這將有助於清理事情。

String s1 = "This is"; 
    s1 = s1 + " my book"; // Note the space 
    String s2 = "This is my book"; 
    String s3 = "This is my book"; 
    System.out.println(s1==s2); // False 
    System.out.println(s2==s3); // True 

「只有當字符串被顯式實例化或由類使用字面值時纔會將字符串放入池中。」因此,您不能將字符串與+運算符連接起來,並希望將其放入字符串常量池中。

+0

我們走吧!有人訪問了鏈接! – csmckelvey

+1

不完全正確。連接兩個常量將會保持不變。 –

+0

@ TomHawtin-tackline你能解釋一下嗎? – Christian

-1

+運算符的存在會產生新的字符串。這裏s1 = s1 + " my book",s1 +「我的書」隱含地創建新的String並將其對s1的引用存儲起來。所以它不同於s2

2

首先,你缺少一個空間。我認爲這只是一個錯誤。

你可能已經看到這樣的事情:

"This is"+" my book" == "This is my book" 

爲什麼工作?因爲這全是編譯時常量JLS 7 15.28。特別是「字符串類型的文字」和「添加劑操作符+和 - 」。

還有「引用常量變量的簡單名稱」。但是這不適用,因爲你的變量不是final

但這不是你應該特別需要了解的。 String s只需使用equals