package com.example.demo.test;
 
 
/**
 * <p>
 * <code>StringBuilderTest</code>
 * </p>
 * Description: JDK 1.8
 *
 * @author Jalen
 * @date 2019/8/26 9:41
 */
public class StringBuilderTest {
 
    public static void main(String[] args) {
        //createString();
        //createEmptyStringBuilder();
        createNonEmptyStringBuilder();
    }
 
    private static void createString(){
        //编译期优化,直接将string赋值为"abc",可以使用javap -verbose xxx.class查看
        String string = "a" + "b" + "c";
        System.out.println(string);
 
        //使用+号连接字符串等同于使用StringBuilder的append方法拼接字符串,
        //可以使用javap -verbose xxx.class查看字节码
        String a = "a";
        String b = "b";
        String c = "c";
        String str = a + b + c;
        System.out.println(str);
    }
 
    /**
     * 创建容量为空的StringBuilder
     * 调用链1:
     *      {@link java.lang.StringBuilder#StringBuilder}
     *          这里调用父类构造方法,同时赋值capacity为默认值16
     *      {@link java.lang.AbstractStringBuilder#AbstractStringBuilder(int)}
     *          这里初始化一个长度为16的字节数组(char[])
     * 调用链2:
     *      {@link java.lang.StringBuilder#append(String)}
     *          这里调用父类的append方法,将当前字符串传给父类
     *      {@link java.lang.AbstractStringBuilder#append(String)}
     *          if (str == null)
     *              return appendNull();
     *          int len = str.length();  //这里length为1
     *          ensureCapacityInternal(count + len); //第一次append,count为0
     *          str.getChars(0, len, value, count);
     *          count += len;  //count累加
     *          return this;
     *      {@link java.lang.AbstractStringBuilder#ensureCapacityInternal(int)}
     *          if (minimumCapacity - value.length > 0) { //这里minimumCapacity=1,value长度为16(即上面初始化时赋予的16个长度的容量)
     *             value = Arrays.copyOf(value, newCapacity(minimumCapacity));
     *          }
     *      {@link java.lang.String#getChars}
     *          if (srcBegin < 0) {
     *             throw new StringIndexOutOfBoundsException(srcBegin);
     *          }
     *          if (srcEnd > value.length) {
     *             throw new StringIndexOutOfBoundsException(srcEnd);
     *          }
     *          if (srcBegin > srcEnd) {
     *             throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
     *          }
     *          System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin); //调用native方法将append的字符串以char数组形式copy到value里
     *       count += len; //count重新赋值
     * 调用链3:
     *      {@link java.lang.StringBuilder#append(int)}
     *      {@link java.lang.AbstractStringBuilder#append(int)}
     *          if (i == Integer.MIN_VALUE) {
     *             append("-2147483648");
     *             return this;
     *          }
     *          int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1 : Integer.stringSize(i);
     *          int spaceNeeded = count + appendedLength;
     *          ensureCapacityInternal(spaceNeeded);
     *          Integer.getChars(i, spaceNeeded, value);
     *          count = spaceNeeded;
     *          return this;
     *      {@link java.lang.Integer#stringSize(int)}
     *          for (int i=0; ; i++)
     *             if (x <= sizeTable[i]) //sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE }
     *                 return i+1;
     *      {@link java.lang.AbstractStringBuilder#ensureCapacityInternal(int)}
     *          if (minimumCapacity - value.length > 0) {
     *             value = Arrays.copyOf(value, newCapacity(minimumCapacity));
     *          }
     *      {@link java.lang.Integer#getChars}
     *      count = count + appendedLength;
     * 调用链4:
     *      {@link java.lang.StringBuilder#append(boolean)}
     *      {@link java.lang.AbstractStringBuilder#append(boolean)}
     *      {@link java.lang.AbstractStringBuilder#ensureCapacityInternal(int)}
     * 调用链5:
     *      {@link java.lang.StringBuilder#append(char)}
     *      {@link java.lang.AbstractStringBuilder#append(char)}
     *      {@link java.lang.AbstractStringBuilder#ensureCapacityInternal(int)}
     * 调用链6:
     *      {@link java.lang.StringBuilder#append(long)}
     *      {@link java.lang.AbstractStringBuilder#append(long)}
     *         if (l == Long.MIN_VALUE) {
     *             append("-9223372036854775808");
     *             return this;
     *         }
     *         int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
     *                                      : Long.stringSize(l);
     *         int spaceNeeded = count + appendedLength;
     *         ensureCapacityInternal(spaceNeeded);
     *         Long.getChars(l, spaceNeeded, value);
     *         count = spaceNeeded;
     *         return this;
     */
    @SuppressWarnings("all")
    private static void createEmptyStringBuilder(){
        //这里等同于上面的String str = a + b + c
        StringBuilder sb = new StringBuilder(); //1
        sb.append("a");                         //2
        sb.append("b");
        sb.append(1);                           //3
        sb.append(true);                        //4
        sb.append('c');                         //5
        sb.append(99L);                         //6
        System.out.println(sb.toString());
    }
 
    /**
     * 创建包含初始容量的StringBuilder
     * 调用链1:
     *      {@link java.lang.StringBuilder#StringBuilder(int)}
     *      {@link java.lang.AbstractStringBuilder#AbstractStringBuilder(int)}
     *          value = new char[capacity]; //capacity=3
     * 调用链2:
     *      {@link java.lang.StringBuilder#append(String)}
     *      {@link java.lang.AbstractStringBuilder#append(String)}
     *      {@link java.lang.AbstractStringBuilder#ensureCapacityInternal(int)}
     *         if (minimumCapacity - value.length > 0) { //minimumCapacity=2, value.length=3
     *             value = Arrays.copyOf(value, newCapacity(minimumCapacity));
     *         }
     *      {@link java.lang.String#getChars}
     *          System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
     *      count += len;
     * 调用链3:
     *      {@link java.lang.StringBuilder#append(String)}
     *      {@link java.lang.AbstractStringBuilder#append(String)}
     *      {@link java.lang.AbstractStringBuilder#ensureCapacityInternal(int)}
     *         if (minimumCapacity - value.length > 0) { //minimumCapacity=4, value.length=3
     *             value = Arrays.copyOf(value, newCapacity(minimumCapacity)); //value扩容
     *         }
     *      {@link java.util.Arrays#copyOf(float[], int)}
     *         float[] copy = new float[newLength];
     *         System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
     *         return copy;
     *      {@link java.lang.AbstractStringBuilder#newCapacity(int)}
     *         int newCapacity = (value.length << 1) + 2; //value.length=3, newCapacity=8
     *         if (newCapacity - minCapacity < 0) { //minCapacity=4
     *             newCapacity = minCapacity;
     *         }
     *         return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
     *             ? hugeCapacity(minCapacity) : newCapacity;
     *      {@link java.lang.String#getChars}
     *          System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
     *      count += len;
     */
    @SuppressWarnings("all")
    private static void createNonEmptyStringBuilder(){
        StringBuilder sb = new StringBuilder(3); //1
        sb.append("aa"); //2
        sb.append("bb"); //3,触发扩容
        System.out.println(sb.toString());
    }
}

扩容方法

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    public static final int MAX_VALUE = 0x7fffffff;
 
    private int newCapacity(int minCapacity) {
        // overflow-conscious code
        int newCapacity = (value.length << 1) + 2;
        if (newCapacity - minCapacity < 0) {
            newCapacity = minCapacity;
        }
        return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
            ? hugeCapacity(minCapacity)
            : newCapacity;
    }
 
 
    private int hugeCapacity(int minCapacity) {
        if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
            throw new OutOfMemoryError();
        }
        return (minCapacity > MAX_ARRAY_SIZE)
            ? minCapacity : MAX_ARRAY_SIZE;
    }

StringBuffer 扩容方式与 StringBuilder 基本一致