分析一下字节码就知道了。
// Compiled from StringDemo.java (version 1.5 : 49.0, super bit)
public class collections.StringDemo {
// Method descriptor #6 ()V
// Stack: 1, Locals: 1
public StringDemo();
0 aload_0 [this]
1 invokespecial java.lang.Object() [8]
4 return
Line numbers:
[pc: 0, line: 6]
Local variable table:
[pc: 0, pc: 5] local: this index: 0 type: collections.StringDemo
// Method descriptor #15 ([Ljava/lang/String;)V
// Stack: 5, Locals: 4
public static void main(java.lang.String[] args);
0 ldc [16]
2 astore_1 [str]
3 ldc [18]
5 astore_2 [str2]
6 ldc [20]
8 astore_3 [str3]
9 getstatic java.lang.System.out : java.io.PrintStream [22]
12 aload_1 [str]
13 new java.lang.StringBuilder [28]
16 dup
17 aload_2 [str2]
18 invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [30]
21 invokespecial java.lang.StringBuilder(java.lang.String) [36]
24 aload_3 [str3]
25 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [39]
28 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [43]
31 if_acmpne 38
34 iconst_1
35 goto 39
38 iconst_0
39 invokevirtual java.io.PrintStream.println(boolean) : void [47]
42 getstatic java.lang.System.out : java.io.PrintStream [22]
45 aload_1 [str]
46 new java.lang.StringBuilder [28]
49 dup
50 ldc [18]
52 invokespecial java.lang.StringBuilder(java.lang.String) [36]
55 aload_3 [str3]
56 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [39]
59 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [43]
62 if_acmpne 69
65 iconst_1
66 goto 70
69 iconst_0
70 invokevirtual java.io.PrintStream.println(boolean) : void [47]
73 getstatic java.lang.System.out : java.io.PrintStream [22]
76 aload_1 [str]
77 ldc [16]
79 if_acmpne 86
82 iconst_1
83 goto 87
86 iconst_0
87 invokevirtual java.io.PrintStream.println(boolean) : void [47]
90 return
Line numbers:
[pc: 0, line: 8]
[pc: 3, line: 9]
[pc: 6, line: 10]
[pc: 9, line: 11]
[pc: 42, line: 12]
[pc: 73, line: 13]
[pc: 90, line: 15]
Local variable table:
[pc: 0, pc: 91] local: args index: 0 type: java.lang.String[]
[pc: 3, pc: 91] local: str index: 1 type: java.lang.String
[pc: 6, pc: 91] local: str2 index: 2 type: java.lang.String
[pc: 9, pc: 91] local: str3 index: 3 type: java.lang.String
}
现在一个个的分析:
ldc表示将int, float或String型常量值从常量池中推送至栈顶.
astore表示将栈顶引用型数值存入指定本地变量
那么
ldc [16]
2 astore_1 [str]
表示 abc 在运行时常量池中间取出,并且将引用赋给str变量。
同理,str1,str2都一样。
那么这就说明一个问题:
类似于String str1="dddd"说明"dddd"字符串存在运行时常量池中,而不是存在堆中间。
然后看s2+s3:
new java.lang.StringBuilder [28]
16 dup
17 aload_2 [str2]
18 invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [30]
21 invokespecial java.lang.StringBuilder(java.lang.String) [36]
24 aload_3 [str3]
25 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [39]
28 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [43]
java运算符重载了加法。也就是字符串的加号是通过StringBuilder的append和toString来完成的。查看toString的源码:
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
很显然是新生成了一个String,引用地址不一样,那么"=="判断当然为false。
然后看
"a" + str3
ldc [18]
52 invokespecial java.lang.StringBuilder(java.lang.String) [36]
55 aload_3 [str3]
56 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [39]
59 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [43]
62 if_acmpne 69
65 iconst_1
```
不用看。既然是StringBuilder那么也一定是false了、
最后"a"+"bc"
```java
iconst_0
70 invokevirtual java.io.PrintStream.println(boolean) : void [47]
73 getstatic java.lang.System.out : java.io.PrintStream [22]
76 aload_1 [str]
77 ldc [16]
79 if_acmpne 86
说明,对于这种情况,java编译器做了优化。直接存储在运行时常量池中间。那么当然为true。
那么C#。。。。不知道他们运行机制是咋样的。