手记

Java的String相关的加号+和append比较

上例子:
package com.smile.core;

public class StringAppend {

public static void main(String[] args) {    // 字符串常量用+连成串,实际上等于一个字符串,效率最高    long start = System.currentTimeMillis();    String str = null;    for (int i = 0; i < 100000; i++) {        str = "this" + " is" + " only" + " a" + " test.";    }    System.out.println("123: " + (start - System.currentTimeMillis()));    // 通过+=来把常量字符或者变量连成串,其过程相当于String str = new StringBuilder().append("a").append(s).toString();     // 效率最慢    start = System.currentTimeMillis();    String str1 = null;    String aStr = " a";    for (int i = 0; i < 100000; i++) {        str1 = "this is";        str1 += " only";        str1 += aStr;        str1 += " test.";    }    System.out.println("234: " + (start - System.currentTimeMillis()));    // 和上一种方法相比,少了String.valueOf()、new StringBuilder()、StringBuilder.toString()的过程    // 效率其次    start = System.currentTimeMillis();    StringBuffer sb = null;    for (int i = 0; i < 100000; i++) {        sb = new StringBuffer().append("this ").append("is ").append("only ").append("a ").append("test.");    }           System.out.println("345: " + (start - System.currentTimeMillis()));    /* result     * 123: 0       234: -78       345: -47     */}

}
生成的class文件(标出关键的地方):

  4  aconst_null  5  astore_3 [str]  6  iconst_0  7  istore 4 [i]  9  goto 18 12  ldc <String "this is only a test."> [22] 14  astore_3 [str] 15  iinc 4 1 [i] 18  iload 4 [i] 20  ldc <Integer 100000> [24] 22  if_icmplt 12 55  aconst_null 56  astore 4 [str1] 58  ldc <String " a"> [49] 60  astore 5 [aStr] 62  iconst_0 63  istore 6 [i] 65  goto 141 68  ldc <String "this is"> [51] 70  astore 4 [str1] 72  new java.lang.StringBuilder [29] 75  dup 76  aload 4 [str1] 78  invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [53] 81  invokespecial java.lang.StringBuilder(java.lang.String) [33] 84  ldc <String " only"> [59] 86  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [61] 89  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [40] 92  astore 4 [str1] 94  new java.lang.StringBuilder [29] 97  dup 98  aload 4 [str1]100  invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [53]103  invokespecial java.lang.StringBuilder(java.lang.String) [33]106  aload 5 [aStr]108  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [61]111  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [40]114  astore 4 [str1]116  new java.lang.StringBuilder [29]119  dup120  aload 4 [str1]122  invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [53]125  invokespecial java.lang.StringBuilder(java.lang.String) [33]128  ldc <String " test."> [64]130  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [61]133  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [40]136  astore 4 [str1]178  aconst_null179  astore 6 [sb]181  iconst_0182  istore 7 [i]184  goto 224187  new java.lang.StringBuffer [68]190  dup191  invokespecial java.lang.StringBuffer() [70]194  ldc <String "this "> [71]196  invokevirtual java.lang.StringBuffer.append(java.lang.String) : java.lang.StringBuffer [73]199  ldc <String "is "> [76]201  invokevirtual java.lang.StringBuffer.append(java.lang.String) : java.lang.StringBuffer [73]204  ldc <String "only "> [78]206  invokevirtual java.lang.StringBuffer.append(java.lang.String) : java.lang.StringBuffer [73]209  ldc <String "a "> [80]211  invokevirtual java.lang.StringBuffer.append(java.lang.String) : java.lang.StringBuffer [73]214  ldc <String "test."> [82]216  invokevirtual java.lang.StringBuffer.append(java.lang.String) : java.lang.StringBuffer [73]219  astore 6 [sb]

}

这样看的很清楚吧,每种方法执行时的步骤明明白白的写在class文件中。
附上class指令说明(摘自http://blog.csdn.net/hudashi/article/details/7062675):
一、const系列
该系列命令主要负责把简单的数值类型送到栈顶。
指令码     助记符                            说明
0x02         iconst_m1                   将int型(-1)推送至栈顶
0x0a         lconst_1                      将long型(1)推送至栈顶
0x0d         fconst_2                      将float型(2)推送至栈顶
0x0e         dconst_0                     将double型(0)推送至栈顶
二、push系列
该系列命令负责把一个整形数字(长度比较小)送到到栈顶。该系列命令有一个参数,用于指定要送到栈顶的数字。
注意该系列命令只能操作一定范围内的整形数值,超出该范围的使用将使用ldc命令系列。
指令码    助记符                            说明
0x10          bipush    将单字节的常量值(-128~127)推送至栈顶
0x11           sipush    将一个短整型常量值(-32768~32767)推送至栈顶
三、ldc系列
该系列命令负责把数值常量或String常量值从常量池中推送至栈顶。该命令后面需要给一个表示常量在常量池中位置(编号)的参数,
哪些常量是放在常量池呢?比如:final static int id=32768;final static float double=6.5。
对于const系列命令和push系列命令操作范围之外的数值类型常量,都放在常量池中.
另外,所有不是通过new创建的String都是放在常量池中的。
指令码    助记符                               说明
0x12            ldc                 将int, float或String型常量值从常量池中推送至栈顶
0x13          ldc_w               将int, float或String型常量值从常量池中推送至栈顶(宽索引)
0x14          ldc2_w             将long或double型常量值从常量池中推送至栈顶(宽索引)
四、load系列
该系列命令负责把本地变量的送到栈顶。这里的本地变量不仅可以是数值类型(iload、lload、fload、dload),还可以是引用类型(aload),还可以是数组的某项(aaload)。
五、store系列
该系列命令负责把栈顶的值存入本地变量。这里的本地变量不仅可以是数值类型,还可以是引用类型、还可以把栈顶项的值存到数组里。
六、pop系列
弹出栈顶的值
七、其他操作
swap 互换
add 相加
sub 相减
mul 相乘
div 相除
rem 取模
neg 取负
shl 左移位
shr 右移位
and 按位与
or 按位或
xor 按位异或

0人推荐
随时随地看视频
慕课网APP