String、StringBuffer、StringBuilder

刚开始学习时,书籍、老师、教程都只介绍到 String 不可变,StringBuffer 线程安全,StringBuilder 线程不安全,一直都是死记硬背,还总是弄糊涂,现知其然知其所以然。

String

String 类对象代表不可变的Unicode字符序列,所以称为不可变对象。

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;
}

private final char value[];
String字符串值是存储在 char 类型的 value[] 数组中,而数组定义是为 final 的,所以 String 类型赋值后不可变。
而我们对 String 对象的改变,实际是生成新的对象,改变指针指向。
若常改变字符串内容使用 String,将会产生许多对象,对系统性能产生影响,所以最好不使用 String。



StringBuffer

StringBuffer继承AbstractStringBuilder

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

而 AbstractStringBuilder 中字符串也是存储在 char value[],但是并没有 final 修饰,所以 StringBuffer 是可变的,修改值 hashCode 地址没变。

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char[] value;

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

StringBuffer是线程安全的,因为其方法都添加了同步锁 synchronized ,所以一般使用在全局变量

@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);
    }

    /**
     * @since      1.5
     */
    @Override
    public synchronized void trimToSize() {
        super.trimToSize();
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     * @see        #length()
     */
    @Override
    public synchronized void setLength(int newLength) {
        toStringCache = null;
        super.setLength(newLength);
    }

    /**
     * @throws IndexOutOfBoundsException {@inheritDoc}
     * @see        #length()
     */
    @Override
    public synchronized char charAt(int index) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        return value[index];
    }


StringBuilder

StringBuilder继承AbstractStringBuilder,同样可变,修改值 hashCode 地址没变。

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

StringBuffer是非线程安全的,因为其方法是直接继承 AbstractStringBuilder 的,未添加同步锁。所以一般使用在局部变量,用完后丢弃

    /**
     * Returns the length (character count).
     *
     * @return  the length of the sequence of characters currently
     *          represented by this object
     */
    @Override
    public int length() {
        return count;
    }

    /**
     * Returns the current capacity. The capacity is the amount of storage
     * available for newly inserted characters, beyond which an allocation
     * will occur.
     *
     * @return  the current capacity
     */
    public int capacity() {
        return value.length;
    }

    /**
     * Ensures that the capacity is at least equal to the specified minimum.
     * If the current capacity is less than the argument, then a new internal
     * array is allocated with greater capacity. The new capacity is the
     * larger of:
     * <ul>
     * <li>The {@code minimumCapacity} argument.
     * <li>Twice the old capacity, plus {@code 2}.
     * </ul>
     * If the {@code minimumCapacity} argument is nonpositive, this
     * method takes no action and simply returns.
     * Note that subsequent operations on this object can reduce the
     * actual capacity below that requested here.
     *
     * @param   minimumCapacity   the minimum desired capacity.
     */
    public void ensureCapacity(int minimumCapacity) {
        if (minimumCapacity > 0)
            ensureCapacityInternal(minimumCapacity);
    }

    /**
     * For positive values of {@code minimumCapacity}, this method
     * behaves like {@code ensureCapacity}, however it is never
     * synchronized.
     * If {@code minimumCapacity} is non positive due to numeric
     * overflow, this method throws {@code OutOfMemoryError}.
     */
    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }


*
String:String中对象是不可变的,可理解为常量,即线程安全的。
StringBuffer:对象可变,线程安全,效率比 String 高。
StringBuilder:对象可变,线程不安全,效率比 StringBuffer 高(常用,官方推荐优先使用,因为速度快)。



说明:

StringBuffer 在 JDK1.0 引入,StringBuilder 在 JDK1.5引入,都是直接继承 Object 类,没有继承 AbstractStringBuilder 抽象类,----------咦,有问题,研究研究,是API文档中不显示 Abstract 类?都显示直接继承 Object,我使用的是1.8,这里又是继承的 AbstractStringBuilder 类?2018/9/27 2:12

为啥速度快?
String消耗创建对象时间,所以慢,StringBuilder比StringBuffer快,是因为StringBuffer的方法添加的同步锁,会影响性能,所以StringBuffer慢点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值