代码优化:尽量重用对象。StringBuilder/StringBuffer/+


重点注意:对象

特别是String对象的使用,出现字符串拼接时应该使用StringBuilder/StringBuffer代替。由于Java虚拟机不仅要花时间生成对象,以后可能还需要花时间对这些对象进行垃圾回收和处理,因此,生成过多的对象将会给程序的性能带来很大的影响。

字符串的拼接在开发过程中使用是非常频繁的,常用的方式有三种:

(1)、+ 号拼接: str+"456"

(2)、StringBuilder 拼接

(3)、StringBuffer拼接

StringBuffer是保证线程安全的,效率是比较低的,我们更多的是使用场景是不会涉及到线程安全的问题的,所以更多的时候会选择StringBuilder,效率会高一些

那么,问题来了,StringBuilder和“+”号拼接,哪个效率高呢?接下来我们通过字节码的方式进行探究。

public class Test3 {
    public static void main(String[] args) {
        new Test3().m1();
        new Test3().m2();
    }
    public void m1(){
        String s1 = "123";
        String s2 = "456";
        String s3 = s1 + s2;
        System.out.println(s3);
    }
    public void m2(){
        String s1 = "123";
        String s2 = "456";
        StringBuilder sb = new StringBuilder();
        sb.append(s1);
        sb.append(s2);
        String s3 = sb.toString();
        System.out.println(s3);
    }
}

查看 Test3.class的字节码,从解字节码中可以看出, m1()方法源码中是使用+号拼接,但是在字节码中也被编译成了StringBuilder方式

所以,可以得出结论,字符串拼接,+号和StringBuilder是相等的,效率一样。

接下来,我们再看一个案例:

public class Test4 {
    public static void main(String[] args) {
        new Test4().m1();
        new Test4().m2();
    }
    public void m1(){
        String str = "";
        for (int i = 0; i < 5; i++) {
            str = str + i;
        }
        System.out.println(str);
    }
    public void m2(){
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 5; i++) {
            sb.append(i);
        }
        System.out.println(sb.toString());
    }
}

m1() 与 m2() 哪个方法的效率高?依然是通过字节码的方式进行探究。可以看到, m1()方法中的循环体内,每一次循环都会创建StringBuilder对象,效率低于m2()方法。

接下来,我们看一个案例:

public class Test4 {
    public static void main(String[] args) {
        new Test4().m1();
        new Test4().m2();
    }
    public void m1(){
        String str = "";
        for (int i = 0; i < 5; i++) {
            str = str + i;
        }
        System.out.println(str);
    }
    public void m2(){
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 5; i++) {
            sb.append(i);
        }
        System.out.println(sb.toString());
    }
}

m1() 与 m2() 哪个方法的效率高?

m1()方法中的循环体内,每一次循环都会创建StringBuilder对象,效率低于m2()方法。当用+号进行一次字符串拼接的时候都会new一个StringBuilder,循环5次就会new 5个StringBuilder对象。m2()方法中在循环体内并没有new StringBuilder对象,而是每次都是调用append方法,即在循环体外new了一次,在循环体内一直append,而new对象和销毁对象(垃圾回收)都会占用系统资源。

总结:for循环中字符串拼接用StringBuilder