【发布时间】:2014-08-13 09:46:19
【问题描述】:
我运行以下代码并获得 cmets 中显示的结果。我知道== 和.equals() 之间的区别。我不明白的是为什么我在第二行的代码与第三行的代码有不同的结果。
String de = "de";
// String abcde = "abc" + "de"; // abcde == "abcde" reture true
String abcde = "abc" + de; // abcde == "abcde" reture false;
System.out.println();
System.out.println(abcde=="abcde");
System.out.println(de=="de");
在尝试调试时,我使用了 javap -c 命令并为第一个字符串连接获得了以下输出“代码”:
Code:
0: ldc #9; //String de
2: astore_1
3: new #10; //class java/lang/StringBuilder
6: dup
7: invokespecial #11; //Method java/lang/StringBuilder."<init>":()V
10: ldc #4; //String abc
12: invokevirtual #12; //Method java/lang/StringBuilder.append:(Ljava/lang
String;)Ljava/lang/StringBuilder;
15: aload_1
16: invokevirtual #12; //Method java/lang/StringBuilder.append:(Ljava/lang
String;)Ljava/lang/StringBuilder;
19: invokevirtual #13; //Method java/lang/StringBuilder.toString:()Ljava/l
ng/String;
22: astore_2
23: getstatic #14; //Field java/lang/System.out:Ljava/io/PrintStream;
26: invokevirtual #15; //Method java/io/PrintStream.println:()V
29: getstatic #14; //Field java/lang/System.out:Ljava/io/PrintStream;
32: aload_2
33: ldc #16; //String abcde
35: if_acmpne 42
38: iconst_1
39: goto 43
42: iconst_0
43: invokevirtual #17; //Method java/io/PrintStream.println:(Z)V
46: getstatic #14; //Field java/lang/System.out:Ljava/io/PrintStream;
49: aload_1
50: ldc #9; //String de
52: if_acmpne 59
55: iconst_1
56: goto 60
59: iconst_0
60: invokevirtual #17; //Method java/io/PrintStream.println:(Z)V
63: return
以及第二个字符串连接的输出:
我对这个“代码”不太熟悉,也看不出存在这些差异的任何原因。那么谁能解释为什么会出现这些差异?
相关post
【问题讨论】:
-
这里的实际问题是什么? (我假设您已经知道
==比较字符串 references,而不是字符串 contents)? -
请看
String.equals(....)方法,它和==操作符不一样... -
要了解“那些代码”...您可以参考JVM instruction set document。
-
JVM 在实例化字符串字面量时进行优化,即如果字符串字面量已经存在于 String Literal Pool 中,它每次都返回相同的引用。因此,所有具有值“abcde”的文字都指向同一个内存位置。 "==" 只比较引用,并且由于所有 "abcde" 的内存位置相同,因此它返回 true。 "abc"+de 使用 diff 内存地址创建一个新的 String 对象,因此 == 将它的内存地址与 "abcde" 进行比较,并且由于地址是 diff,它返回 false。
-
"==" 是浅比较。如果两个对象指向同一个内存引用,则返回 true。 “.equals”是深度比较。它按值比较两个对象,如果它们包含相同的值,则返回true。