StringBuffer与StringBuilder源码分析+值传递&引用传递
StringBuffer与StringBuilder源码分析+值传递&引用传递
在之前的博文中介绍了Java中String那些不为人知的事情,本篇博文旨在理解StringBuffer与StringBuilder,并能够清楚在实际应用中能个最优选择String或StringBuffer,亦或StringBuilder。
继承结构
StringBuffer和StringBuilder都继承于AbstractStringBuilder,在AbstractStringBuilder中定义了基本数据capcity等,还实现了capcity容量不足时的扩充函数实现供StringBuffer与StringBuilder直接使用。
并且细细观察到StringBuffer和StringBuilder的API基本相同,设计者的目的是为了在线程安全下使用StringBuffer类,在线程非安全下使用StringBuilder。
StringBuffer源码分析
StringBuffer是JDK1.0版本出现的,是线程安全的(如下图:源码中的synchronized标志)
StringBuffer中含有capcity变量记录StringBuffer的容量,默认容量为16;当append的字符串超出默认容量时,就进行capcity扩充。源码注解如下:
默认capcity大小为16 。如下图:
当以传入初始值的方式创建StringBuffer时,capcity会在传入的Object的基础上+16。如下图:
StringBuffer在扩充时,采用2倍空间扩充。如下图:
StringBuilder源码分析
StringBuilder源码与StringBuffer源码非常相近,但是StringBuilder与StringBuffer关键性的区别是线程安全问题,StringBuilder是线程非安全的。如下图:(没有synchronized标识)
拓展知识:值传递&引用传递
值传递
值传递:针对基础类型,如:int、char、double、float、String;在作为参数传递给方法时,不会改变原值。
引用传递
引用传递:针对非基础类型,如:包装类(Integer、Character)、自定义类等;在作为参数传递给方法时,会改变原值。
下面以String和StringBuffer为例进行实验证明:
代码清单如下
public class Test4StringAndStringBuffer
{
public static void main(String[] args)
{
//test String
String s="you";
System.out.println("String before value:"+s);
changeString(s);//the test function
System.out.println("String after value:"+s);
//test StringBuffer
StringBuffer sb=new StringBuffer("you");
System.out.println("StringBuffer before value:"+sb);
changeStringBuffer(sb); //the test function
System.out.println("StringBuffer after value:"+sb);
}
private static void changeStringBuffer(StringBuffer sb)
{
sb.append("are best!");
}
private static void changeString(String a)
{
a=a+"are the best man";
}
}
运行结果如下图
实验结果表明String属于值传递,传参后的值未发生改变;StringBuffer属于引用传递,传参后的值发生改变。
String、StringBuffer和StringBuilder你都懂了吧!保持对Java源码的关注,将会使你懂的比别人更多!加油!
谢谢阅读 ----知飞翀