String/StringBuffer/StringBuilder的区别

简单区分

String: 字符串,一旦创建不可更改
StringBuffer:字符串构造器,可以修改字符串内容,线程安全
StringBuilder:同StringBuffer,线程不安全

String由于创建之后不可更改,所以改变String的操作其实是新生成了一个新的String对象,所以频繁改变的字符串建议使用StringBuffer/StringBuider。

StringBuffer VS StringBuilder

StringBuilder是在Java 5中提出的,跟StringBuffer有相同的接口,但不是线程安全的。

在Java 8中,分析源码可以看到,两者父类相同,实现了同样的接口。摘抄源码代码段如下:

 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence

有兴趣的同学可以看一下这两个类,实现基本差不多,StringBuffer为了保证线程安全在相关函数上加了synchronized关键字。

我在阅读源码时发现StringBuffer有一个变量toStringCache,而StringBuilder没有,查阅了一下资料,可能是历史原因。参见:https://stackoverflow.com/questions/46294579/why-stringbuffer-has-a-tostringcache-while-stringbuilder-not

String 拼接的编译优化

从Java 5开始,Java就对String字符串的+操作进行了优化,主要有两种优化。

  1. 常量的拼接
    如果拼接内容为常量,比如:String a = "Hello " + "World"; 应该被直接优化为了String a = "Hello World;
  2. 需要运行时确定内容的拼接
    拼接内容如果有非 常量,会将+优化为StringBuilder的append操作
    如下:
public class StringTest {
    public static void main(String[] args) {
        String a = "Hello ";
        String b = a + "World";
        String c = b + "!";
    }
}

优化后代码类似于:

public class StringTest {
    public static void main(String[] args) {
        String a = "Hello ";
        String b = new StringBuilder().append(a).append("World").toString();
        String c = new StringBuilder().append(b).append("!").toString();
    }
}

有兴趣的同学可以创建一个简单类,编译上面两段代码,编译出的class文件应该是一样的。
直接编译StringTest类javac StringTest.java
查看class文件:javap -verbose StringTest.class

我这里贴一个优化前代码编译出的代码片段String拼接优化

关于常量拼接有一个比较好的文章,直接贴链接:https://bbs.csdn.net/topics/300264665

虽然编译器有一定程度的优化,但是在字符串变动较多时,还是要要使用StringBuffer/StringBuilder,如上面的例子,其实哪怕优化后也是新建了两个StringBuilder,在循环中这种情况更为明显。

使用总结

  1. 字符串为常量的拼接,可以直接使用String
  2. 字符串一经定义极少修改,使用String
  3. 字符串变动较多使用StringBuffer/StringBuilder
  4. 单线程(不要求线程安全)使用StringBuilder,多线程(要求线程安全)使用StringBuffer。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值