栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

从源码分析String、StringBuffer、StringBuilder之间的区别与联系

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

从源码分析String、StringBuffer、StringBuilder之间的区别与联系

文章目录
  • String、StringBuffer、StringBuilder类的定义
    • 区别一
  • String、StringBuffer、StringBuilder的构造函数
    • 区别二
  • StringBuffer、StringBuilder的部分方法
    • 区别三
  • 总结

String、StringBuffer、StringBuilder类的定义

我们首先来分析以下String、StringBuffer、StringBuilder三个类在源码中的定义:

  • String
public final class String
    implements java.io.Serializable, Comparable, CharSequence
public interface CharSequence 
  • StringBuffer
public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
abstract class AbstractStringBuilder implements Appendable, CharSequence
public interface Appendable
  • StringBuilder
public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence

可见,String、StringBuffer、StringBuilder都实现了Serializable(序列化)接口,其他的继承实现关系如下图所示:

下面对上图中涉及到的一些类做一个解释:

类名解释
AbstractStringBuilder这个抽象类是StringBuilder和StringBuffer的直接父类,实现可修改的字符串。在任何时间点,它都包含一些特定的字符序列,但是序列的长度和内容可以通过某些方法调用来更改。
Appendable接口定义字符串添加的’规则’(append()方法)
CharSequence接口是一个可读的char值序列。这接口提供了对多种不同类型数据的统一只读访问char序列。
区别一

由于StringBuilder和StringBuffer继承了AbstractStringBuilder ,所以StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象;而String的值是不可变的,每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间。

String、StringBuffer、StringBuilder的构造函数
  • String
    参考:从源码分析String类中的常用方法
  • StringBuffer
	public StringBuffer() {
        super(16);
    }

    
    public StringBuffer(int capacity) {
        super(capacity);
    }

    
    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

    
    public StringBuffer(CharSequence seq) {
        this(seq.length() + 16);
        append(seq);
    }
  • StringBuilder
    public StringBuilder() {
        super(16);
    }

    
    public StringBuilder(int capacity) {
        super(capacity);
    }

    
    public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }

    
    public StringBuilder(CharSequence seq) {
        this(seq.length() + 16);
        append(seq);
    }
区别二

每个StringBuffer、StringBuilder对象都有一定的缓冲区容量(初始大小为16),当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。

StringBuffer、StringBuilder的部分方法
  • StringBuffer
@Override
    public synchronized int length() {
        return count;
    }

    @Override
    public synchronized int capacity() {
        return value.length;
    }

    @Override
    public synchronized void ensureCapacity(int minimumCapacity) {
        super.ensureCapacity(minimumCapacity);
    }

    @Override
    public synchronized void trimToSize() {
        super.trimToSize();
    }

    
    @Override
    public synchronized void setLength(int newLength) {
        toStringCache = null;
        super.setLength(newLength);
    }

    
    @Override
    public synchronized char charAt(int index) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        return value[index];
    }

    @Override
    public synchronized int codePointAt(int index) {
        return super.codePointAt(index);
    }

    @Override
    public synchronized int codePointBefore(int index) {
        return super.codePointBefore(index);
    }

    @Override
    public synchronized int codePointCount(int beginIndex, int endIndex) {
        return super.codePointCount(beginIndex, endIndex);
    }
  • StringBuilder
@Override
    public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }

    
    @Override
    public StringBuilder delete(int start, int end) {
        super.delete(start, end);
        return this;
    }

    
    @Override
    public StringBuilder deleteCharAt(int index) {
        super.deleteCharAt(index);
        return this;
    }

    
    @Override
    public StringBuilder replace(int start, int end, String str) {
        super.replace(start, end, str);
        return this;
    }

    
    @Override
    public StringBuilder insert(int index, char[] str, int offset,
                                int len)
    {
        super.insert(index, str, offset, len);
        return this;
    }

    
    @Override
    public int indexOf(String str) {
        return super.indexOf(str);
    }

    @Override
    public StringBuilder reverse() {
        super.reverse();
        return this;
    }

    @Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }

    
    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
        s.defaultWriteObject();
        s.writeInt(count);
        s.writeObject(value);
    }

    
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        s.defaultReadObject();
        count = s.readInt();
        value = (char[]) s.readObject();
    }
区别三

StringBuffer中的方法都有synchronized关键字修饰,而StringBuilder没有,所以StringBuffer线程安全,而StringBuilder线程不安全。

总结
StringStringBufferStringBuilder
String的值是不可变的,每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间StringBuffer类的对象能够被多次的修改,并且不产生新的未使用对象,有一定的缓冲区容量(初始大小为16),当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。StringBuilder类的对象能够被多次的修改,并且不产生新的未使用对象,有一定的缓冲区容量(初始大小为16),当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。
不可变类可变类可变类
线程安全线程不安全
多线程操作字符串单线程操作字符串

StringBuilder提供一个与 StringBuffer 兼容的 API,但不保证同步。StringBuilder被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/591398.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号