StringBuffer源码解析

在重写ArrayList的toString方法时,查看了StringBuffer的源码.
//new StringBuffer("[");构造方法public StringBuffer(String str) {    super(str.length() + 16);    append(str);}//super(str.length() + 16);调用父类构造AbstractStringBuilder(int capacity) {    //初始化value数组 char[] value;length为参数字符串长度+16    value = new char[capacity];}public AbstractStringBuilder append(String str) {    if (str == null)        return appendNull();    int len = str.length();    //保证内部数组容量,拼接字符串str长度+内部数组实际长度 大于 buffer对象内部value数组长度则扩容内部数组    //内部数组实际长度指{1,2,3,null,null},实际长度为3,数组长度为5    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));    }}//original内部数组扩容为newLength长度public static char[] copyOf(char[] original, int newLength) {    char[] copy = new char[newLength];    //Math.min(original.length, newLength)复制长度为原来数组的长度    System.arraycopy(original, 0, copy, 0,                     Math.min(original.length, newLength));    return copy;}//新数组长度计算算法private int newCapacity(int minCapacity) {    // overflow-conscious code    // 原来数组长度*2再+2    int newCapacity = (value.length << 1) + 2;    if (newCapacity - minCapacity < 0) {        //如果原来数组长度*2再+2还是 小于 拼接字符串str长度+内部数组实际长度 则设置新数组长度为:拼接字符串str长度+内部数组实际长度        newCapacity = minCapacity;    }    //判断新数组长度是否大于Integer.MAX_VALUE - 8 int类型最大值,大于则抛出OutOfMemoryError内存不足异常    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;}// str.getChars(0, len, value, count);public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {    if (srcBegin < 0) {        throw new StringIndexOutOfBoundsException(srcBegin);    }    if (srcEnd > value.length) {        throw new StringIndexOutOfBoundsException(srcEnd);    }    if (srcBegin > srcEnd) {        throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);    }    //this.value数组是str字符串的内部数组,从index=0开始复制,复制到目标数组(dst:buffer的value内部数组)    //目标数组的下标位置(从index=count的位置开始复制:也就是value[count]开始复制),要复制的长度:str字符串的长度    //要复制的数组(源数组),复制源数组的起始位置,目标数组,目标数组的下标位置,要复制的长度    System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);}

原文地址:https://www.cnblogs.com/yuancoco/p/11699809.html

时间: 2024-10-20 03:50:15

StringBuffer源码解析的相关文章

String源码解析(一)

本篇文章内的方法介绍,在方法的上面的注释讲解的很清楚,这里只阐述一些要点. Java中的String类的定义如下: 1 public final class String 2 implements java.io.Serializable, Comparable<String>, CharSequence { ...} 可以看到,String是final的,而且继承了Serializable.Comparable和CharSequence接口. 正是因为这个特性,字符串对象可以被共享,例如下面

Java String源码解析

String类概要 所有的字符串字面量都属于String类,String对象创建后不可改变,因此可以缓存共享,StringBuilder,StringBuffer是可变的实现 String类提供了操作字符序列中单个字符的方法,比如有比较字符串,搜索字符串等 Java语言提供了对字符串连接运算符的特别支持(+),该符号也可用于将其他类型转换成字符串. 字符串的连接实际上是通过StringBuffer或者StringBuilder的append()方法来实现的 一般情况下,传递一个空参数在这类构造函

JDK源码及其他框架源码解析随笔地址导航

置顶一篇文章,主要是整理一下写过的JDK中各个类的源码解析以及其他框架源码解析的文章,方便自己随时阅读也方便网友朋友们阅读及指正 基础篇 从为什么String=String谈到StringBuilder和StringBuffer Java语法糖1:可变长度参数以及foreach循环原理 Java语法糖2:自动装箱和自动拆箱 集合篇 图解集合1:ArrayList 图解集合2:LinkedList 图解集合3:CopyOnWriteArrayList 图解集合4:HashMap 图解集合5:不正确

String源码解析

定义 先看一下文档中的注释 12345 * Strings are constant; their values cannot be changed after they * are created. String buffers support mutable strings. * Because String objects are immutable they can be shared. */ String对象是常量,创建之后就不能被修改,所以该对象可以被多线程共享. 123456789

死磕 Java 系列(一)&mdash;&mdash; 常用类(1) String 源码解析

写在前面 这是博主新开的一个 java 学习系列,听名字就可以看出来,在这一些系列中,我们学习的知识点不再是蜻蜓点水,而是深入底层,深入源码.由此,学习过程中我们要带着一股钻劲儿,对我们不懂的知识充满质疑,力求把我们学过的知识点都搞清楚,想明白. 一.引言 在 java 的世界里,存在一种特殊的类,它们的创建方式极为特别,不需要用到 new XXX(当然也可以用这种方式创建), 但是却大量出现在我们的代码中,那就是 String 类.作为日常中使用频率最高的类,它是那么普通,普通到我们从来都不会

ChrisRenke/DrawerArrowDrawable源码解析

转载请注明出处http://blog.csdn.net/crazy__chen/article/details/46334843 源码下载地址http://download.csdn.net/detail/kangaroo835127729/8765757 这次解析的控件DrawerArrowDrawable是一款侧拉抽屉效果的控件,在很多应用上我们都可以看到(例如知乎),控件的github地址为https://github.com/ChrisRenke/DrawerArrowDrawable

五.jQuery源码解析之jQuery.extend(),jQuery.fn.extend()

给jQuery做过扩展或者制作过jQuery插件的人这两个方法东西可能不陌生.jQuery.extend([deep],target,object1,,object2...[objectN]) jQuery.fn.extend([deep],target,object1,,object2...[objectN])这两个属性都是用于合并两个或多个对象的属性到target对象.deep是布尔值,表示是否进行深度合并,默认是false,不执行深度合并.通过这种方式可以在jQuery或jQuery.fn

eclipse中导入jdk源码、SpringMVC注解@RequestParam、SpringMVC文件上传源码解析、ajax上传excel文件

eclipse中导入jdk源码:http://blog.csdn.net/evolly/article/details/18403321, http://www.codingwhy.com/view/799.html. ------------------------------- SpringMVC注解@RequestParam:http://825635381.iteye.com/blog/2196911. --------------------------- SpringMVC文件上传源

Flume-ng源码解析之Channel组件

如果还没看过Flume-ng源码解析之启动流程,可以点击Flume-ng源码解析之启动流程 查看 1 接口介绍 组件的分析顺序是按照上一篇中启动顺序来分析的,首先是Channel,然后是Sink,最后是Source,在开始看组件源码之前我们先来看一下两个重要的接口,一个是LifecycleAware ,另一个是NamedComponent 1.1 LifecycleAware @[email protected] interface LifecycleAware {  public void s