String、StringBuffer、StringBuilder

String

不可变特性,长度有限制,编译期,存储在常量池中,容量受到常量池最大上限限制,最大是65534;在运行期间,受限于int类型的长度,最大为4GB(参考理解:https://juejin.im/post/5d53653f5188257315539f9a
)。

  • final类,内部使用char value[]保存值。
  • 通过反射可以修改String的value字符数组值
private static void modifyString() {
    String s = "Hello World";
    try {
        // 获取String类中的value字段
        Field valueFieldOfString = String.class.getDeclaredField("value");
        // 改变value属性的访问权限
        valueFieldOfString.setAccessible(true);
        // 获取s对象上的value属性的值
        char[] value = (char[]) valueFieldOfString.get(s);
        // 改变value所引用的数组中的第5个字符
        value[5] = '_';
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}
  • 线程安全
  • 适用场景:不经常修改的情况下,如常量、少量字符串拼接等。

StringBuffer

实现原理,基于可修改的char数组,初始容量16,随着存储的元素越来越多,会尝试扩容,代码如下:

    // 追加元素
    public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        // 计算当(前字符长度+追加字符的长度),并传入ensureCapacityInternal判断是否需要扩容
        ensureCapacityInternal(count + len);
        str.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));
        }
    }

    private int newCapacity(int minCapacity) {
        // overflow-conscious code
        // 原来容量的2倍+2
        int newCapacity = (value.length << 1) + 2;
       // 取newCapacity与minCapacity二者的最大值
        if (newCapacity - minCapacity < 0) {
            newCapacity = minCapacity;
        }
        return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
            ? hugeCapacity(minCapacity)
            : newCapacity;
    }
  • 线程安全
  • 适用场景:在频繁进行字符串的运算(拼接、替换、删除等),并且在多线程环境下,如解析xml,解析http参数,封装http参数等。

StringBuilder

可以理解为StringBuffer的线程非安全版本,特性与StringBuffer基本一致。

  • 非线程安全
  • 适用场景:运行在单线程环境下,如sql语句拼装,JSON封装等。

你可能感兴趣的:(String、StringBuffer、StringBuilder)