文档章节

StringBuffer源码浅析(大致结构和append方法)

明舞
 明舞
发布于 2014/08/19 22:08
字数 748
阅读 43
收藏 0

java的stringbuffer是通过char[]数组实现的。只有当调用stringbuffer的tostring方法才会转换成string对象。

char[]数组有个初始化的值,其初始化长度未16.如果不够则继续申请更多的空间,申请更多的空间用的是arraycopy方法。


StringBuffer类继承自AbstractStringBuilder抽象类,实现Serializable序列化接口和CharSequence接口。

AbstractStringBuilder抽象类实现Appendabel,CharSequence接口。

另外,StringBuilder的源码跟StringBuffer类似,看完Buffer再看Builder,找出不同点看看就大致可以。

 

一,关于append方法浅析。

append方法都做了同步声明,其中源码如下

 

public synchronized StringBuffer append(String str) {
	super.append(str);
        return this;
}

 

1、StringBuffer的方法都加了synchronized关键字,线程安全。

2、synchronized代表方法加锁,例如线程A,要运行到声明了synchronized 方法时,先检查有没有其他线程B,C正在使用这synchronized 方法,若有就先等B,C线程运行完这个synchronized 方法后,在运行A,若无直接运行,

3、synchronized两种用法:synchronized方法和synchronized块。

synchronized(syncObject) {  // synchronized代码块
  //允许访问控制的代码
}

4、围观append源码

     第一步:StringBuffer类体内

 

/*

 *  可见是通过super调用父类AbstractStringBuilder中定义的append方法。
 */
public synchronized StringBuffer append(StringBuffer sb) {
        super.append(sb);
        return this;
}

 

 

    第二步:AbstractStringBuilder抽象类体内

 

/**
 *  AbstractStringBuilder属性有:
 *          char value[];  // The value is used for character storage(). 容量
 *          int count;  // The count is the number of characters used.实际字符数
 */
public AbstractStringBuilder append(StringBuffer sb) {
	if (sb == null)
            return append("null");
	int len = sb.length();
	int newCount = count + len;  
	if (newCount > value.length)
	    expandCapacity(newCount); // 若value存储容量不够需扩容。扩容方法省略暂不分析,基本上根据Arrays.copyOf()方法,复制指定的数组,以使副本具有指定的长度。到头来copyOf的源码一样是利用arraycopy方法来复制数组和扩容
	sb.getChars(0, len, value, count); // 把sb的内容0->len复制到value中,注意value参数,此时的value是已经扩容后的value。
	count = newCount;  // 更新新count值
	return this;
}

    原有count要加上len(len也就是新增的count)成newCount,若这newCount总数要大于原有value的容量,就要     扩容才可以容纳newCount个字符。再用getChars复制数组。

 

    第三步:AbstractStringBuilder里定义的getChars方法体,是对System.arraycopy方法 + 边界检查的进一步封装                 而已。

 

public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) //  dstBegin就是原有count接下来的位置
    {
	if (srcBegin < 0)
	    throw new StringIndexOutOfBoundsException(srcBegin);
	if ((srcEnd < 0) || (srcEnd > count))
	    throw new StringIndexOutOfBoundsException(srcEnd);
        if (srcBegin > srcEnd)
            throw new StringIndexOutOfBoundsException("srcBegin > srcEnd"); //以上是Bound Check
	System.arraycopy(value, srcBegin,dst, dstBegin, srcEnd - srcBegin);  // 从指定源数组中复制一个数组
}

    arraycopy方法参数

          src - 源数组。

  • srcPos - 源数组中的起始位置。

  • dest - 目标数组。

  • destPos - 目标数据中的起始位置。

  • length - 要复制的数组元素的数量。 

  •     注意value和dst

    这个value是sb.value,srcEnd-srcBegin个元素全部复制dst(也就是扩容的value)中。(这里我理解正确吗?)

     

    待续...

© 著作权归作者所有

明舞
粉丝 227
博文 424
码字总数 516555
作品 0
程序员
私信 提问
Java深究之String、StringBuffer、StringBuilder的区别

在Java学习中,String、StringBuffer、StringBuilder三者是很重要的,在编写代码中经常使用到他们,那么深入的了解他们的异同是非常重要的,接下里我们详细剖析下这三个的异同之处 首先总结下...

MaxBill
2018/07/02
0
0
为什么说StringBuilder线程不安全

一、前言 可能大家在学习java的基础过程中,都知道StringBuilder相对StringBuffer效率更高,但是线程不安全。可是,到底是怎么个不安全法,反正我是懵的。借此机会,写个小代码测试下。 二、...

叫我宫城大人
2017/09/08
0
0
java中String、StringBuffer、StringBuilder的区别 - jihite

java中String、StringBuffer、StringBuilder的区别 - jihite 博客园jihite2018-01-011 阅读 StringBufferjavaString Java里面提供了String,StringBuffer和StringBuilder三个类来封装字符串 ......

博客园_jihite
2018/01/01
0
0
String ,  StringBuffer ,  StringBuilder的区别

String , StringBuffer , StringBuilder的区别 String 首先,String 是用来表示一个字符串常量的,它是一个不可变对象,意味着,一旦我们创建了某个字符串之后,就不能再改变它的值了,我们可...

tsmyk0715
2018/10/17
0
0
StringBuilder 与 StringBuffer 源码分析

简介 StringBuilder 与 StringBuffer 是两个常用的操作字符串的类。 大家都知道, StringBuilder 是线程不安全的,而 StringBuffer 是线程安全的。前者是JDK1.5加入的,后者在JDK1.0就有了。...

皮蛋瘦肉粥里没有粥
2016/03/03
33
0

没有更多内容

加载失败,请刷新页面

加载更多

【AI实战】手把手教你深度学习文字识别(文字检测篇:基于MSER, CTPN, SegLink, EAST等方法)

文字检测是文字识别过程中的一个非常重要的环节,文字检测的主要目标是将图片中的文字区域位置检测出来,以便于进行后面的文字识别,只有找到了文本所在区域,才能对其内容进行识别。 文字检...

雪饼
48分钟前
3
0
思维导图XMind 8 Pro 绿化方法(附序列号)

按部就班: Step 1 -全新下载最新版本的 Xmind 8(注必须是英文官方的版本,中文代{过}{滤}理网站的版本修改过,无法使用pj); Step 2 -安装完毕后,点击文末的下载按钮下载pj补丁文件包,将...

一只小青蛙
今天
6
0
数据结构(ER数据库)设计规范

表命名规范 表命名的规则分为3个层级,层级之间通过_分割,例如b_r_identity、d_l_identity。规约为: [leavel]_[type]_[name] [leavel] 表示数据库表的层级和功能,分为: s:业务无关的系统...

随风溜达的向日葵
今天
5
0
阿里Sentinel控制台源码修改-对接Apollo规则持久化

https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel 动态规则扩展 https://github.com/alibaba/Sentinel/wiki......

jxlgzwh
昨天
5
0
在Linux系统中创建SSH服务器别名

如果你经常通过 SSH 访问许多不同的远程系统,这个技巧将为你节省一些时间。你可以通过 SSH 为频繁访问的系统创建 SSH 别名,这样你就不必记住所有不同的用户名、主机名、SSH 端口号和 IP 地...

老孟的Linux私房菜
昨天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部