JAVA从入门到进阶(八)——String,StringBuffer和StringBuilder的区别

String与StringBuffer,StringBuider的区别

1.简单地说,就是一个变量和常量的关系.StringBuffer对象的内容可以修改;而字符串对象一旦产生后就不可以被修改,重新赋值其实是两个对象
的StringBuffer的内部实现方式和字符串不同,StringBuffer的在进行字符串处理时,不生成新的对象,在内存使用上要优于串类。所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入,删除等操作,使用StringBuffer要更加适合一些。
我们从底层代码分析看到

string类

public final class String
    implements java.io.Serializable, Comparable<String>, 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
     * <a href="{@docRoot}/../platform/serialization/spec/output.html">
     * Object Serialization Specification, Section 6.2, "Stream Elements"</a>
     */
    private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];

String类的底层代码是由字符数组实现的,并且定义为final类型,其值为常量,不可改变。

StringBuffer类是继承AbstratStringBuider抽象类,可以看到用来实现的字符数组没有定义为final,可以对字符串本身进行修改,而不产生新的对象。

  /**
     * The value is used for character storage.
     */
    char[] value;

    /**
     * The count is the number of characters used.
     */
    int count;

    /**
     

通过对底层代码的比较得知:String类是一个常量,赋值后不能被改变。
StringBuffer和StringBuider类是一个变量,赋值后可以进行修改。
拓展:当我们连接字符串时,通过StringBuffer类连接比String类连接资源开销小。
例:String s1=“ds”;
String s2=“kk”;
String s3=s1+s2;
因为String底层未不可变的字符串,所以会创建三个对象,都会占用内存,而这三个对象一直都未失去引用,所以jvm无法垃圾回收,造成内存资源的大量浪费,这在我们开发中是不推崇的,而StringBuilder 与StringBuffer则不存在这样的问题。
对StringBuffer类的底层代码分析,通过判断字符数组长度是否足够,从而创建一个新的数组用来封装数据,而原来的对象被放弃引用,等待垃圾回收,从而减少内存的浪费。

 AbstractStringBuilder append(AbstractStringBuilder asb) {
        if (asb == null)
            return appendNull();
        int len = asb.length();
        ensureCapacityInternal(count + len);
        asb.getChars(0, len, value, count);
        count += len;
        return this;`
      
           private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }

2.执行区别
StringBuffer和StringBuider
StringBuffer底层代码

   public synchronized int length() {
        return count;
    }

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


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

大都加了同步函数,每进入一次函数就会判断锁。
StringBuider类

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

    @Override
    public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }

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

未加同步锁,不需要判断锁资源。
①StringBuffer在多线程时是安全的,StringBuider只适合单一线程来运行。
②在多线程执行时,我们用StringBuffer。在单线程执行时,用StringBuider,因为不需要判断同步锁,执行效率更高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值