重载“+”与StringBuilder

2019 Java 开发者跳槽指南.pdf (吐血整理)….>>>

摘自《think in Java》第四版

String对象是不可变的。涉及String值的操作都是创建了一个全新的String对象,原来的String值一点也没有变。用于String的“+”与“+=”是Java中仅有的两个重载过的操作符,并不允许程序员重载任何操作符。

操作符“+”可以用来连接String:

public class Concatenation{
    public static void main(String args[]){
       String mango =  "mango";
       String s = "abc" + mango + "def" + 47;
       System.out.println(s);                 
    }    
}

接着我们用JDK自带的工具javap进行反编译以上代码,命令如下:

javac Concatenation.java
javap -c Concatenation

重载“+”与StringBuilder

从上图可以看出编译器创建了一个StringBuilder对象,用以构造最终的String,并为每一个字符串调用了一次StringBuilder的append()方法,总计四次。最后调用toString()生成结果。

编译器对String的优化
public class WhitherStringBuilder {  
    public String implicit(String[] fields) 
        String result = "";  
        for (int i = 0; i < fields.length; i++)   
            result += fields[i];   
        return result;  
    } 


    public String explicit(String[] fields) {  
        StringBuilder result = new StringBuilder(); 
        for (int i = 0; i < fields.length; i++)  
            result.append(fields[i]);  
        return result.toString();  
    }  
}

接着用反编译器进行编译一下,首先是implicit()方法:

重载“+”与StringBuilder

从上图可以注意到从第8行到第35行是一个循环体,每循环一次,都会创建一个新的StringBuilder对象。接着来看下explicit()方法对应的字节码:

重载“+”与StringBuilder

从上图可以看出不仅循环部分的代码更简短、更简单,而且它只生成了一个StringBuilder对象。

StringBuilder特点

可以为StringBuilder预先指定大小,如果知道最终的字符串长度,可以预先指定StringBuilder的大小,以避免多次重新分配缓冲。

如果要在toString()方法中使用循环的话,最好自己创建一个StringBuidler对象。

StringBuidler提供了丰富而全面的方法,包括insert(),replace(), substring(),reverse(),最常用的方法是append()和toString()方法。

StringBuilder线程不安全,效率高,StringBuffer 线程安全,效率低。



原文始发于微信公众号(一盏红茶):重载“+”与StringBuilder