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:真
答案 0 :(得分: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
“字符串只有在明确地或通过类使用文字时才放入池中。”因此,您不能使用+运算符连接字符串,并期望将其放入字符串常量池中。
答案 1 :(得分: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
答案 2 :(得分:2)
首先,你错过了一个空间。我认为这只是一个错误。
您可能已经看到过类似的内容:
"This is"+" my book" == "This is my book"
为什么这样做?因为它都是编译时常量 JLS 7 15.28。特别是“String类型的文字”和“添加运算符+和 - ”。
还有“简单名称[...]引用常量变量”。但这并不适用,因为您的变量不是final
。
但这不是你应该特别需要知道的事情。只需将equals
用于String
s。
答案 3 :(得分: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);
}
}
因为 Strings 是对象,它们的==行为与int,chars和其他原语不同。
答案 4 :(得分:-1)
+运算符的存在会导致新的String。这里s1 = s1 + " my book"
,s1 +“我的书”隐式创建新的String并存储其对s1的引用。所以它与s2不同