前几天,有个同事问了我一个表面看起来显而易见的问题,是关于String的,咱们一块儿来看一下(若是有说的不正确的地方,欢迎你们指正)。java
java中,字面量在编译期计算,而且String字面量做为常量,存储在方法区中,仅保留一份。带有变量的计算,在运行期执行。那么,str3在执行的时候,发生了什么。数组
第一步,初始化一个StringBuilder对象,并在构造器中调用父类AbstractStringBuilder的构造器,初始化一个长度16的字符数组app
第二步,调用StringBuilder的append()方法,传入变量str1,内部调用父类AbstractStringBuilder的append()方法性能
在入参不为null的状况下,先调用ensureCapacityInternal()方法,判断拼接后的字符串长度是否超过当前字符数组的长度。若是超过了,就计算一个新的长度,而后建立一个新的数组,将现有数组的值复制给它,ui
具体扩容规则是,将当前字符数组长度扩容一倍再加2,若是扩容后的数组长度还不够,就和Integer.MAX_VALUE - 8(即MAX_ARRAY_SIZE)比较,若是还不够,则就用拼接后的字符串长度,可是最大也不能超过Integer.MAX_VALUE。(有一个newCapacity <= 0的判断,是考虑到value.length << 1变负数;至于扩容一倍还要+2,我的觉得是为了提升性能,广泛计算得出,若是有不一样理解,欢迎你们评论)3d
第三步,调用str.getChars()方法,将入参字符串拼接到现有的字符数组后面,实际操做是调用本地方法对象
System.arraycopy()。
第四步,记录下字符个数,最后返回当前StringBuilder对象。blog
第五步,拼接字符串”bbb”,重复第二步到第四步,ci
最后,调用StringBuilder的toString方法,去掉多余的空字符,返回一个当前累计字符长度的String对象,字符串
其实也是调用本地方法System.arraycopy()。复制一个新的字符数组。正好符合String的不变类特性。