string类型的比较 java_Java(C#)String类型的比较

分析一下字节码就知道了。

java// 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表示将栈顶引用型数值存入指定本地变量

那么

javaldc [16]

2 astore_1 [str]

表示 abc 在运行时常量池中间取出,并且将引用赋给str变量。

同理,str1,str2都一样。

那么这就说明一个问题:

类似于String str1="dddd"说明"dddd"字符串存在运行时常量池中,而不是存在堆中间。

然后看s2+s3:

javanew 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的源码:

javapublic String toString() {

// Create a copy, don't share the array

return new String(value, 0, count);

}

很显然是新生成了一个String,引用地址不一样,那么"=="判断当然为false。

然后看

java"a" + str3

javaldc [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#。。。。不知道他们运行机制是咋样的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值