java stringbuffer原理_Java之——深入解析String、StringBuffer、StringBuiler

要说Java中什么哪个类用的最频繁,要数String类了。所以说,关于String 、StringBuffer、StringBuilder 是有必要详细研究一下的。

那么这三者之间有什么区别,如何根据场景来选择使用,本文将基于三者的源码、性能、以及面试常问点来进行分析。

String 类

我们先看看String的源码,看看Sting到底是个什么样的类

public final class String

implements java.io.Serializable, Comparable, CharSequence {

/** The value is used for character storage. */

private final char value[];

/** Cache the hash code for the string */

private int hash; // Default to 0

/** use serialVersionUID from JDK 1.0.2 for interoperability */

private static final long serialVersionUID = -6849794470754667710L;

/*** Class String is special cased within the Serialization Stream Protocol.** A String instance is written into an ObjectOutputStream according to* * Object Serialization Specification, Section 6.2, "Stream Elements"*/

private static final ObjectStreamField[] serialPersistentFields =

new ObjectStreamField[0];

可见,String类实现了CharSequence 接口,也就是说 String 是 CharSequence 类型。而且它是被final修饰的类,且底层的字符数组也是被final修饰的,这就意味着一旦String被定义之后就是固定的,不可改变的。

今天之所以要引入这个话题,是因为在做字符串拼接时的效率问题进行分析,我们在做简单的字符串拼接时,底层原理其实是创建新对象和回收旧对象的过程,这其中牵扯到了GC(垃圾回收机制),举个例子就明白了

String s1 = "abc" ;//1 s1 = s1 + "d" ;//2 System.out.println(s1);//3

可以看出,首先定义一个字符串s1,赋值为"abc",在执行第二行代码时,其实就是在原有s1的基础上拼接一个新的字符串"d",然后形成新的s1打印输出。

这个过程中,GC会回收旧的s1对象,同时创建新的对象(s1),但是这样的拼接过程在涉及到大量的字符串拼接时,就显得捉襟见肘了。

所以要想办法优化一下字符拼接,所以就出现了StringBuffer以及StringBuiler。

StringBuffer 类

StringBuffer 类继承自类AbstractStringBuilder,AbstractStringBuilder 类封装了大量基础方法,包括数组扩容机制、拼接方法等。

StringBuffer 初始化时默认长度大小为 16,它的扩容方式是在旧的数据上乘以 2 并加 2 进行扩容,StringBuffer实现字符串拼接用到了append 方法,这里摘抄一下append 方法的源码

@Override

public synchronized StringBuffer append(Object obj) {

toStringCache = null;

super.append(String.valueOf(obj));

return this;

}

@Override

public synchronized StringBuffer append(String str) {

toStringCache = null;

super.append(str);

return this;

}

可以看到,Stringbuffer底层的append方法是被synchronized标识的,因此StringBuffer是线程安全的,所以总的来说,StringBuffer提高了线程安全性,但是牺牲了效率。

StringBuiler 类

StringBuilder 与 StringBuffer 是类似的,都是继承自AbstractStringBuilder,所以很多功能都相似,但是不同的是它们的append方法不同,StringBuilder的append方法,不是由synchronized标识,所以相对于StringBuffer来说,StringBuilder不是线程安全的。

@Override

public StringBuilder append(Object obj) {

return append(String.valueOf(obj));

}

@Override

public StringBuilder append(String str) {

super.append(str);

return this;

}

所以说,StringBuffer和StringBuilder相对于String来说,极大地提高了字符串拼接的效率,在使用时选择怎样选择呢?

一般的话,对于字符串拼接较少、字符串变化较小的的情况,可以选择String

当字符串连接操作比较频繁,且要求线程安全(多线程环境下操作)时,选择StringBuffer

而StringBuiler 适用于字符串连接操作比较频繁,且是单线程的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值