关于String累加

昨天在群里跟人讨论关于String累加的问题,貌似没有人能特别准确的知道是一个什么样的情况,今天我通过jclasslib (PS:从 http://zangxt.iteye.com/搞到的好东西)来检测一下编译器是如何进行字符串累加的,我们先写一段代码:
package francis;  
public class TestString {  
    public static void main(String[]args) {  
        String s = "";  
        for(int i = 0; i < 1000; i++) {  
            s += i;  
        }  
        System.out.println(s);  
    }  
}  

很简单,貌似网上也能给出一个大概的结论,但是我们还是亲手看一下编译后的代码:
关于String累加
我们可以看到上面的程序被编译成了22行的代码,我们注意看一下第6行到第18行,这是整个for循环所执行的代码,我们会很明显的看到,每次循环都会执行第6行的代码,也就是每次都会新建了一个StringBuilder对象,这多么浪费性能啊。

这就很明显了,每一次字符串的拼接,编译器都是通过新建StringBuilder对象来完成的。

哎,如果编译器足够智能,将新建StringBuilder对象放到循环之外,就不用我们去操心性能问题,但是,貌似目前编译器还办不到。所以我们手动的新建StringBuilder是比较好的方案:
package francis;  
public class TestString {  
    public static void main(String[]args) {  
        String s = "";  
        StringBuilder sb = new StringBuilder(s);  
        for(int i = 0; i < 1000; i++) {  
            sb.append(i);  
        }  
        s = sb.toString();  
        System.out.println(s);  
    }  
}  

为了确定是否真的达到效果,我们来看一下这次编译后的代码:
关于String累加
这次循环的代码是在11~18行,而创建StringBuilder对象是在第三步执行。这样就避免了编译器会每个循环都新建一个StringBuilder对象了。比较好的习惯就是当连接字符串操作比较多的时候直接手动新建StringBuilder对象.

那有人可能会问了,String的每次拼接都是利用创建StringBilder对象来处理么? 实践乃检验真理的唯一方法:

先写代码:
package francis;  
public class TestString {  
    public static void main(String[]args) {  
        String a = "a" + "b" + "c";  
        String b = a + "b";  
        String c = a + b;  
        System.out.println(a + b + c);  
    }  
} 

然后再看一下编译后的结果,由于比较长,我分成两张图片:
关于String累加
关于String累加
很显然,有四个new StringBuilder操作。基本可以得出结论:需要字符串连接的时候,如果没有可用的对应的StringBuilder就会去新建。因此字符串操作还是推荐自己手动去new StringBuilder,不能依赖编译器的优化。

当然会有很多其它情况,比如我在第三行代码后面加一个c+=a;a+=b;会产生什么样的情况呢?实践乃检验真理的唯一方法,自己去检测吧~~

你可能感兴趣的:(C++,c,C#)