Java核心代码(三)javap跟踪String类"+"加号验证

用javap -c Test 在JDK5.0下,做实验。

实验一 

  String str = "a" + "b";

  // 将字符串 ab 压入常数池

  0:  ldc    #2; //String ab 

  编译器在编译时产生的字节码已经将 "a" + "b" 优化成了 "ab", 

  “字符串常量相加”的相加也会被优化处理。

实验二

  String str = "a" + (1 + 2);

  // 将字符串 a3 压入常数池

  0:  ldc    #2; //String a3 

  虚拟机对其进行同样的优化。

  常量间的相加并不会引起效率问题

试验三

  String s = "b";

  String str = "a" + s;

  // 将字符串 b 压入常数池 

  0:  ldc    #2; //String b 

  // 将引用存放到 1 号局部变量中 

  2:  astore_1

  // 检查到非常量的相加,这时创建 StringBuilder 对象 

  3:  new    #3; //class java/lang/StringBuilder 

  // 从栈中复制出数据,即把字符串 b 复制出来 

  6:  dup 

  // 调用 StringBuilder 的初始构造 

  7:  invokespecial  #4; //Method java/lang/StringBuilder." <init>":()V 

  // 将字符串 a 压入常数池 

  10:  ldc    #5; //String a 

  // 调用 StringBuilder 的 append 方法,把字符串 a 添加进去 (第一次append)

  12:  invokevirtual  #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 

  // 从 1 号局部变量中加载数据引用 

  15:  aload_1 

  // 调用 StringBuilder 的 append 方法,把字符串 b 添加进去  (第二次append)

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

  // 调用 StringBuilder 的 toString 方法 

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

  // 将 toString 的结果保存至 2 号局部变量 

  22:  astore_2 

  23:  return 

  变量中存放的是字符串的地址引用, 因为在编译时无法确定它具体的值,无法对其进行优化处理,

  这时为了达到连接的效果,其内部采用了 StringBuilder 的机制进行处理

  String str = "a" + s;等同于

  String str = new StringBuilder().append("a").append(s).toString(); 

  String str = "a" + s + "b";等同于

  String str = new StringBuilder().append("a").append(s).append("b").toString(); 

  string“+”降低效率是这种情况,for循环中会降低效率,@@@@@@@@@@@@@

        return a + "hhhh-" + "aaaa- " + "bbbb-" + "cccc-";和

        return a.append("hhhh-").append("aaaaa-").append("bbbbb-").append("ccccc-").toString();

        效率上基本上没区别。

  不相信权威教条传说。相信JVM。

    String s1="abc";

    for(int i=0;i<3;i++){s1=s1+"def";}

    0:   ldc     #2; //String abc

    7:   if_icmpge       36

    10:  new     #3; //class java/lang/StringBuilder

    StringBuilder s1=new StringBuilder("abc");

    for(int i=0;i<3;i++){s1=s1.append("def");}

    0:   new     #2; //class java/lang/StringBuilder

    4:   ldc     #3; //String abc

    6:   invokespecial   #4; //Method java/lang/StringBuilder."<init>":(Ljava/lan

    14:  if_icmpge       30

JVM常见指令 

Code:

 0:   iconst_0                //和for循环有关

 1:   istore_2

 2:   iload_2

 3:   iconst_3

 4:   if_icmpge       19        //和for循环有关,到第19行结束

 7:   aload_0

 8:   aload_1

 9:   invokevirtual   #14; //Method java/lang/StringBtring;)Ljava/lang/StringBuilder;

 12:  pop

 13:  iinc    2, 1               //和for循环有关,计数器?第2,1行?

 16:  goto    2                  //和for循环有关,跳转到第2行?

 19:  aload_0

 20:  invokevirtual   #15; //Method java/lang/StringBg/String;

 23:  areturn

猜你喜欢

转载自luckywnj.iteye.com/blog/1722401