在上周的文章中,我们讲了字符串拼接的多种方式,在StringBuilder和StrngBuffer的抽象父类AbstractStringBuilder的append方法中,我们使用了ensureCapacityInternal函数,今天我就带大家看看了解下这个函数

上期的链接:java-字符串拼接的多种方式(1)

//调用函数,这里的调用顺序就是自上而下的
private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
        //从0开始复制数组本身,并采用新的长度
        value = Arrays.copyOf(value,
                newCapacity(minimumCapacity));
        }
}
//返回新的容量
private int newCapacity(int minCapacity) {
        // overflow-conscious code
        //在这里,正数的左移1位指2进制的数左移一位,再用0补充;如原来是0011(3),左移为0110(6)
        //他们的十进制之间的关系是2倍的关系,即2的一次方
        int newCapacity = (value.length << 1) + 2;
        //当新的容量仍然小于实际需要的长度的时候
        if (newCapacity - minCapacity < 0) {
            newCapacity = minCapacity;
        }
        //举例,当value.length为2136372536的时候,newCapacity的符号位由于溢出而改变,
        //超过int的最大值,因此符号位变成了"1",也就是由正数变成负数,这时便满足<=0条件
        return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
                ? hugeCapacity(minCapacity)
                : newCapacity;
}
//用于巨大的新容量的获取
//个人理解:数据和对象的长度并不是真正的由MAX_ARRAY_SIZE来决定,而是由你实际上存储的jvm虚拟机的存储来决定的
//情况1:举个例子,你的int数组的长度是21亿,他需要21亿乘4字节,估算就是8.4G,这通常会超过我们设置的jvm的堆空间大小
//这就是为什么我们超堆内存创建数组的时候,他会报出OutOfMemoryError: Java heap space
//情况2:而当我们超jvm规范创建数据的时候,如Integer.MAX_VALUE-1和Integer.MAX_VALUE;他会报出OutOfMemoryError: Requested array size exceeds VM limit;或许不同的jvm有不同的底线吧
//情况3:而当我们超过Integer.MAX_VALUE,他传递给StringBuilder的值超过了int类型的最大值,底层会变成了负数,他会报出NegativeArraySizeException
private int hugeCapacity(int minCapacity) {
        if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
            throw new OutOfMemoryError();
        }
        //返回最小容量和最大的数组容量中更大的那个
        return (minCapacity > MAX_ARRAY_SIZE)
                ? minCapacity : MAX_ARRAY_SIZE;
    }

总结

1. 个人疑惑:在学习源码的过程中,我在思考为什么MAX_ARRAY_SIZE=Integer.MAX_VALUE - 8,查询说是要存储一些关键的信息?为什么arraylist中的hugeCapacity是可以超过MAX_ARRAY_SIZE的值的,凭什么,你能超出,我却不能?

2. 闲聊:写代码的过程中查询了很多资料,有时候在想为什么要写博客,明明很多人都已经写过了,你再写又有什么意义呢。往大一点说,我想看看别人帅气的代码,了解哪些伟大的程序员所做过的事;往小了说,我以前就希望当我有一天离开这个世界的时候,有本书它记录着我从小到大的生活经历和感悟,写博客也是一种记录吧,也许有一天当我看见这些博客,也会回忆起那些晚上打字的时光,或许那也是一种年轻的回忆呢,哈哈哈!


原来是小袁呐
1 声望0 粉丝