JVM对String常量表达式的处理和优化

1.看看下面这段代码执行结果是什么?
String a = "ab";
String b = "a" + "b";
System.out.println((a == b)); //它的执行结果为true;

2.下面这段代码的执行结果是什么?
String a = "ab";
String bb = "b";
String b = "a" + bb;
System.out.println((a == b)); //执行结果为false

以上两个执行结果的原因分析:
String b = "a" + "b";编译器将这个"a" + "b"作为常量表达式,在编译时进行优化,直接取结果"ab",这样这个问题退化
String a = "ab";
String b = "ab";
System.out.println((a == b));
然后根据3的解释,得到结果true

javap工具执行查看字节码如下:

0: ldc #16; //String ab

2: astore_1

3: ldc #16; //String ab

5: astore_2

6: getstatic #18; //Field java/lang/System.out:Ljava/io/PrintStream;

9: aload_1

10: aload_2

11: if_acmpne 18

14: iconst_1

15: goto 19

18: iconst_0

19: invokevirtual #24; //Method java/io/PrintStream.println:(Z)V

22: return

通过 0: ldc #16; //String ab和 3: ldc #16; //String ab ,知道该java文件通过编译器编译后都变为 String b = "ab"; 和作者分析的一样。

===========================
对于第二个程序这个好理解,"a" + bb中的bb是变量,不能进行优化。javap查看字节码如下:
0: ldc #16; //String ab

2: astore_1

3: ldc #18; //String b

5: astore_2

6: new #20; //class java/lang/StringBuilder

9: dup

10: ldc #22; //String a

12: invokespecial #24; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V

15: aload_2

16: invokevirtual #27; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

19: invokevirtual #31; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;

22: astore_3

23: getstatic #35; //Field java/lang/System.out:Ljava/io/PrintStream;

26: aload_1

27: aload_3

28: if_acmpne 35

31: iconst_1

32: goto 36

35: iconst_0

36: invokevirtual #41; //Method java/io/PrintStream.println:(Z)V

39: return


String+String的操作是在运行时进行的,则会产生新的对象,而不是直接从jvm的string池中获取。


===============================
再看下面两个例子:

String a = "ab";
final String bb = "b";
String b = "a" + bb;
System.out.println((a == b)); //result = true


String a = "ab";
final String bb = getBB();
String b = "a" + bb;
System.out.println((a == b)); //result = false
private static String getBB() {
return "b";
}


查看下面的字节码如下:
0: ldc #16; //String ab

2: astore_1

3: invokestatic #18; //Method getBB:()Ljava/lang/String;

6: astore_2

7: new #22; //class java/lang/StringBuilder

10: dup

11: ldc #24; //String a

13: invokespecial #26; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V

16: aload_2

17: invokevirtual #29; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

20: invokevirtual #33; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;

23: astore_3

24: getstatic #36; //Field java/lang/System.out:Ljava/io/PrintStream;

27: aload_1

28: aload_3

29: if_acmpne 36

32: iconst_1

33: goto 37

36: iconst_0

37: invokevirtual #42; //Method java/io/PrintStream.println:(Z)V

40: return


分析:0: ldc #16; //String ab 变量a的值直接指向常量池中的‘ab’,

通过下面的分析可知 变量2通过StringBuilder进行string操作。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值