Java基础、中级、高级、架构面试资料

Java中String、StringBuffer、StringBuilder的区别

JAVA herman 2490浏览 0评论
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog2,发送下载链接帮助你免费下载!
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云

简要的说,String类型和StringBuffer类型的主要性能区别在于String是不可变的对象,因此在每次对String类型进行改变的时候其实都等同于生成了一个新的String对象,然后再将指针指向新的String对象,所以经常改变内容的字符串最好不要使用String,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后,JVM的GC就会开始工作,那速度是一定会慢的。

而如果使用StringBuffer类则结果就不一样了,每次结果都会对StringBuffer对象本身进行操作,而不是生成新的对象。所以在一般情况下推荐使用StringBuffer,特别是字符串对象经常改变的情况下。而在某些特别情况下,String对象的字符串拼接其实是被JVM解释成了StringBuffer对象的拼接,所以这些时候String对象的速度并不会比StringBuffer对象慢,而特别是以下的字符串对象生成中,String效率要远比StringBuffer快:

String s = "This is only a " + "simple " + "test";
StringBuffer sb = new StringBuffer("This is only a").append.(" simple ").append.(" test");

其实这是JVM的一个小把戏,在JVM眼里,这个String s = "This is only a " + "simple " + "test";其实就是:String s = "This is only a simple test";所以当然不需要太多的时间了,但是这里要注意的是,如果你的字符串是来自另外的String对象的话,速度就没那么快了。比如:

String s2 = "This is only a";
String s3 = "simple ";
String s4 = "test";
String s1 = s2 + s3 + s4;

这时候JVM就会规规矩矩的按照原来的方式去做。
下面是一个简单的String的示例:

public class StringDemo {
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = " World";
        String s3 = s1 + s2;
        String s4 = "Hello World";
        String s5 = "Hello " + "World";
        String s6 = new String("Hello World");
    }
}

String的内存图

如上图1就是上述代码的运行图解,注意String s6 = new String("Hello World");这一段代码执行的时候,是先开辟一个空间,存了Hello World,然后new String后,又开辟了一个空间,所以这一行代码会创建两个字符串对象。不过,由于该代码之前s3、s4、s5都已经指向了一个Hello World了,由于String类型的字符串是不可变可复用的,所以s6这里括号内的Hello World就不用再创建一个对象了。

StringBuffer是线程安全的可变字符序列,一个类似于String的字符串缓冲区,但是不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。StringBuffer 上的主要操作是append和insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。

StringBuilder也是一个可变的字符序列,与StringBuffer的区别是不保证线程安全,用在字符串缓冲区单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数实现中,它比StringBuffer快,二者的方法基本相同。有时候不记得StringBuffer和StringBuilder哪个是线程安全,哪个是线程不安全,可以打开查看下两个的类,搜索下synchronized这个关键字,有这个关键字的就是线程安全的。

综上可以总结得出,String是不可变字符串,StringBuffer和StringBuilder是可变字符串,一般来说,StringBuilder快于StringBuffer快于String,StringBuffer与StringBuilder基本类似,最大的区别在于StringBuffer是线程安全,StringBuilder是非线程安全。

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » Java中String、StringBuffer、StringBuilder的区别