第一个与第二个结果为什么会false?
第三个是2个字符串直接拼接会在常量池中生成新的对象(当对象已存在时候直接返回对象地址),所以str的指向的对象和字符串拼接结果所指向的对象是相同的,不知道这种理解是否有问题?
然而C#中的结果都为true,这2种语言对string类型的维护上有什么不同?求大神解答
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
分析一下字节码就知道了。
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 <String "abc"> [16]
2 astore_1 [str]
3 ldc <String "a"> [18]
5 astore_2 [str2]
6 ldc <String "bc"> [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 <String "a"> [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 <String "abc"> [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表示将栈顶引用型数值存入指定本地变量
那么
表示 abc 在运行时常量池中间取出,并且将引用赋给str变量。
同理,str1,str2都一样。
那么这就说明一个问题:
类似于String str1="dddd"说明"dddd"字符串存在运行时常量池中,而不是存在堆中间。
然后看s2+s3:
java运算符重载了加法。也就是字符串的加号是通过StringBuilder的append和toString来完成的。查看toString的源码:
很显然是新生成了一个String,引用地址不一样,那么"=="判断当然为false。
然后看
说明,对于这种情况,java编译器做了优化。直接存储在运行时常量池中间。那么当然为true。
那么C#。不知道他们运行机制是咋样的。