Java中几种常见字符串的拼接方式及通过源码分析其区别

文章详细介绍了Java中四种常见的字符串拼接方法:使用+直接拼接,concat方法,StringBuilder和StringBuffer的append方法。通过源码分析和性能测试,显示在循环内StringBuilder和StringBuffer效率优于+和concat,其中StringBuilder与StringBuffer唯一的区别在于线程安全性。阿里巴巴Java开发手册建议避免在循环中使用+进行拼接,推荐使用StringBuilder或StringBuffer。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1:使用“+”直接拼接

使用示例:

String str1 = "Hello";
String str2 = "world";
String str = str1 + "," + str2;

"+"其实是Java提供的一个语法糖。

通过反编译上述代码后,可以看到其底层实现是通过将String转换成StringBuilder后,使用append方法进行拼接处理的。如下所示:

String var1 = "Hello";
String var2 = "world";
(new StringBuilder()).append(var1).append(",").append(var2).toString();

当使用“+”时,如果是两个字面量拼接,编译器会在编译期间进行常量折叠。如下所示:

//进行常量折叠后变成 String s = "ab";
String s = "a" + "b";

2:concat

使用示例:

String str1 = "Hello";
String str2 = "world";
String str = str1.concat(str2);

concat源码:

public String concat(String str) {
    int otherLen = str.length();
    if (otherLen == 0) {
        return this;
    }
    int len = value.length;
    char buf[] = Arrays.copyOf(value, len + otherLen);
    str.getChars(buf, len);
    return new String(buf, true);
}

通过源码可以看到,concat的实现原理是通过字符数组拼接,new一个新的String。

3:使用StringBuilder的append方法

使用示例

StringBuilder str1 = new StringBuilder();
str1.append("hello");
str1.append("world");

StringBuilder的append方法源码

public AbstractStringBuilder append(String str) {
    if (str == null)
        return appendNull();
    int len = str.length();
    ensureCapacityInternal(count + len);
    str.getChars(0, len, value, count);
    count += len;
    return this;
}

public StringBuilder append(String str) {
    super.append(str);
    return this;
}

通过源码可以看到StringBuilde继承了AbstractStringBuilder,使用的AbstractStringBuilder中的append方法。其实现原理是直接将需要拼接的字符串,复制到字符数组中,如果字符数组长度不够,则会进行扩展。

4:使用StringBuffer的append方法

使用示例:

StringBuffer str1 = new StringBuffer();
str1.append("hello");
str1.append("world");

StringBuffer的append方法源码:

public AbstractStringBuilder append(String str) {
    if (str == null)
        return appendNull();
    int len = str.length();
    ensureCapacityInternal(count + len);
    str.getChars(0, len, value, count);
    count += len;
    return this;
}

public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}    

通过源码可以看到,StringBuffer和StringBuilder一样,继承了AbstractStringBuilder,并使用其append方法进行拼接,但区别是StringBuffer中的append方法使用了synchronized进行声明,说明这是一个线程安全的方法。

效率比较:

public static void main(String[] args) {
        long t1 = System.currentTimeMillis();
        String str1 = "hello";
        for(int i = 0 ; i < 100000 ; i++ ){
            String str2 = String.valueOf(i);
            str1 = str1 + str2;
        }
        long t2 = System.currentTimeMillis();
        System.out.println(" + 拼接使用时间:" + (t2 - t1));

        long t3 = System.currentTimeMillis();
        String str3 = "hello";
        for(int i = 0 ; i < 100000 ; i++ ){
            String str2 = String.valueOf(i);
            str3 = str3.concat(str2);
        }
        long t4 = System.currentTimeMillis();
        System.out.println(" concat 拼接使用时间:" + (t4 - t3));

        long t5 = System.currentTimeMillis();
        StringBuffer str4 = new StringBuffer("hello");
        for(int i = 0 ; i < 100000 ; i++ ){
            String str2 = String.valueOf(i);
            str4 = str4 .append(str2);
        }
        long t6 = System.currentTimeMillis();
        System.out.println(" StringBuffer.append() 拼接使用时间:" + (t6 - t5));



        long t7 = System.currentTimeMillis();
        StringBuilder str5 = new StringBuilder("hello");
        for(int i = 0 ; i < 100000 ; i++ ){
            String str2 = String.valueOf(i);
            str5 = str5 .append(str2);
        }
        long t8 = System.currentTimeMillis();
        System.out.println(" StringBuilder.append() 拼接使用时间:" + (t6 - t5));
    }

输出结果:

+ 拼接使用时间:14036
concat 拼接使用时间:3793
StringBuffer.append() 拼接使用时间:5
StringBuilder.append() 拼接使用时间:5

StringBuilder <= StringBuffer < concat < +

《阿里巴巴java开发手册》中建议,在循环体内禁止使用“+”进行字符串拼接

总结+使用推荐

  1. 如果是在循环体内进行拼接,则使用StringBuffer或StringBuilder。

  1. 简单的字符串拼接,直接使用“+”即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值