第一个方法返回false,第二个返回true。我的想法:在 test1() 中,当创建 d 时 - 字符串池中已经存在 c。但事实证明 d 是重复的。test2() 的行为对我来说很清楚。你能解释一下在 test1() 中创建 c 和 d 背后的逻辑吗?
public class Main
{
public static void main(String[] args) {
System.out.println("Hello World");
test1();
test2();
}
public static void test1() {
String a = "a";
String b = "b";
// String c = a + b;
String c = a.concat(b);
String d = "ab";
System.out.println(c == d);
}
public static void test2() {
String a = "ab";
String b = "a" + "b";
System.out.println(a == b);
}
}
字节码:
public static void test1();
Code:
0: ldc #7 // String a
2: astore_0
3: ldc #8 // String b
5: astore_1
6: aload_0
7: aload_1
8: invokevirtual #9 // Method java/lang/String.concat:(Ljava/lang/String;)Ljava/lang/String;
11: astore_2
12: ldc #10 // String ab
14: astore_3
15: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
18: aload_2
19: aload_3
20: if_acmpne 27
23: iconst_1
24: goto 28
27: iconst_0
28: invokevirtual #11 // Method java/io/PrintStream.println:(Z)V
31: return
public static void test2();
Code:
0: ldc #10 // String ab
2: astore_0
3: ldc #10 // String ab
5: astore_1
6: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
9: aload_0
10: aload_1
11: if_acmpne 18
14: iconst_1
15: goto 19
18: iconst_0
19: invokevirtual #11 // Method java/io/PrintStream.println:(Z)V
22: return
是否将字符串放入池中取决于编译器。在第二种情况下,他决定两条线都可以放入池中。在第一次测试
c中,它没有进入池中。这解释了测试中的差异。另一个问题是如何与这个程序员相处?
像这样:不要
==在字符串上使用,除非你确定两者都被合并了。用于.intern()将行放入池中。