首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 互联网 >

String种"+"加号验证, 跟踪模式

2012-11-25 
String类+加号验证, 跟踪模式?用javap -c Test 在JDK5.0下,做实验。?实验一?  String str a + b  

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

热点排行