JAVA6可以使用字符串累加

阅读更多

在JAVA6中,编译器会始终对字符串的累加操作做优化编译。

编译器将字符串累加编译成StringBuilder。

源代码

String aa = "aa";
String bb = "bb";
String cc = "cc";
String result = aa + bb + cc;
 
编译后
NEW StringBuilder
    DUP
    ALOAD 1: aa
    INVOKESTATIC String.valueOf(Object) : String
    INVOKESPECIAL StringBuilder.(String) : void
    ALOAD 2: bb
    INVOKEVIRTUAL StringBuilder.append(String) : StringBuilder
    ALOAD 3: cc
    INVOKEVIRTUAL StringBuilder.append(String) : StringBuilder
    INVOKEVIRTUAL StringBuilder.toString() : String
    ASTORE 4: result
 

编译器将字符串累加编译成一个字符串

源代码
String s="aa"+"bb"+"cc";
 
编译后
LDC "aabbcc"
 

最佳实践:先拼接字符串再拼接变量

从上可知第二种字符串累加的效率更高。

aa + "bb"+"cc" 效率小于 "bb"+"cc"+aa。
因为"bb"+"cc"会先编译为"bbcc"。而aa + "bb" + "cc"中出现变量, 在变量后的字符串就会编译成StringBuilder。
源代码
String aa = "aa";
String result3 = aa + "bb"+"cc";
String result4 = "bb"+"cc"+aa;
 
编译后
L0 (0)
    LDC "aa"
    ASTORE 1: aa
   L1 (3)
    NEW StringBuilder
    DUP
    ALOAD 1: aa
    INVOKESTATIC String.valueOf(Object) : String
    INVOKESPECIAL StringBuilder.(String) : void
    LDC "bb"
    INVOKEVIRTUAL StringBuilder.append(String) : StringBuilder
    LDC "cc"
    INVOKEVIRTUAL StringBuilder.append(String) : StringBuilder
    INVOKEVIRTUAL StringBuilder.toString() : String
    ASTORE 2: result3
   L2 (15)
    NEW StringBuilder
    DUP
    LDC "bbcc"
    INVOKESPECIAL StringBuilder.(String) : void
    ALOAD 1: aa
    INVOKEVIRTUAL StringBuilder.append(String) : StringBuilder
    INVOKEVIRTUAL StringBuilder.toString() : String
    ASTORE 3: result4
   L3 (24)
    RETURN
   L4 (26)
 

最佳实践:在循环中不要使用累加操作

因为StringBuilder是在循环内创建的。建议手动在外面创建StringBuilder。

StringBuilder eqPhone = new StringBuilder();
        // 将#转换为-
        for (String phoneNum : wwPhone.split("#")) {
            if (StringUtil.isNotBlank(phoneNum)) {
                eqPhone.append(phoneNum).append("-");
            }
        }
 
源代码:
public static void a()
    {
        String s1="1";
        for (int i = 0; i <10; i++) {
            s1+="2";
        }
    }
 字节码:
 
public static void a();
     0  ldc  [56]
     2  astore_0 [s1]
     3  iconst_0
     4  istore_1 [i]
     5  goto 31
     8  new java.lang.StringBuilder [54] //在循环里创建对象
    11  dup
    12  aload_0 [s1]
    13  invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [77]
    16  invokespecial java.lang.StringBuilder(java.lang.String) [58]
    19  ldc  [69]
    21  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [61]
    24  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [65]
    27  astore_0 [s1]
    28  iinc 1 1 [i]
    31  iload_1 [i]
    32  bipush 10
    34  if_icmplt 8  //跳转到第8行
    37  return
 
分析工具java asm

你可能感兴趣的:(Java,JDK,JVM,SUN,Oracle)