StringBuffer、StringBuilder与String剖析
来源:互联网 发布:郑州财经学院网络管 编辑:程序博客网 时间:2024/05/19 09:50
1 StringBuffer与StringBuilder
StringBuffer与StringBuilder都是final类,不能被继承。
上图是二者的UML图,可以看出,它们都继承了抽象类AbstractBuilder。AbstractBuilder定义了StringBuffer与StringBuilder的基本操作。
这是append方法实现代码:
public AbstractStringBuilder append(String str) {if (str == null) str = "null"; int len = str.length();if (len == 0) return this;int newCount = count + len;if (newCount > value.length) expandCapacity(newCount);str.getChars(0, len, value, count);count = newCount;return this;}public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) { if (srcBegin < 0) { throw new StringIndexOutOfBoundsException(srcBegin); } if (srcEnd > count) { throw new StringIndexOutOfBoundsException(srcEnd); } if (srcBegin > srcEnd) { throw new StringIndexOutOfBoundsException(srcEnd - srcBegin); } System.arraycopy(value, offset + srcBegin, dst, dstBegin, srcEnd - srcBegin); }这是AbstractStringBuilder 中的append方法,实现原理很简单,AbstractStringBuilder 的内部数据结构是字符数组,append方法先判断字符数组长度是否够,如果不够就创建一个更大的字符数组,将原有字符和新字符复制到新建数组中。复制使用的是System类中的arrayCopy方法。
StringBuffer中的append方法:
public StringBuffer(String str) {super(str.length() + 16);append(str);}StringBuilder中的append方法:
public StringBuilder append(String str) {super.append(str); return this;}从这三个方法可以看出,StringBuffer和StringBuilder通过继承,直接调用了父类中方法的实现,那这二者有什么区别呢?
StringBuffer和StringBuilder最大的区别在于:StringBuffer是线程安全的,它的相关方法都加了锁synchronized,StringBuilder是线程不安全的,在单线程环境中,使用StringBuilder比使用StringBuffer效率要高。
2 StringBuffer与String的效率问题
先上一段测试代码:
class Test {public static void main(String args[]) {String s1 = "s1";String s2 = "s2";String s3 = "s3";String s4 = "s4";String s5 = "s1" + "s2" + "s3" + "s4";String s6 = s1 + s2 + s3 + s4;StringBuffer buf = new StringBuffer();buf.append(s1).append(s2).append(s3).append(s4);}}下面是使用DJ Java DCompiler3.7反编译Text.class得到的结果:
class Test{Test(){}public static void main(String args[]){ String s1 = "s1"; String s2 = "s2"; String s3 = "s3"; String s4 = "s4"; String s5 = "s1s2s3s4";//对应 String s5="s1"+"s2"+"s3"+"s4" String s6 = (new StringBuilder(String.valueOf(s1))).append(s2).append(s3).append(s4).toString();//对应String s6=s1+s2+s3+s4; StringBuffer buf = new StringBuffer(); buf.append(s1).append(s2).append(s3).append(s4); }}从反编译的代码中可以看出:
1 String s5 = "s1" + "s2" + "s3" + "s4"
经编译器优化后,变为
String s5 = "s1s2s3s4";
故这二者是等价的
2 String s6 = s1 + s2 + s3 + s4;
反编译之后得到的代码为:
String s6 = (new StringBuilder(String.valueOf(s1))).append(s2).append(s3).append(s4).toString();
已然很明确了,通过“+”进行字符串拼接实际上是调用了StringBuilder的append方法。
这样这两种拼接字符的方法效率就是相同的了。
String str =""; for(int i=0;i<100;i++){ str+=i; }StringBuffer sb =new StringBuffer(); for(int i=0;i<100;i++){ sb.append(i); }如果是这种情况,显然是使用StringBuffer效率要高,前者每次使用字符串拼接都会创建一个StringBuilder对象,然后使用toString方法得到拼接后的字符串,显然多做了一些工作。
关于String的特殊性介绍,请看博客String is special点击打开链接
这里补充一些内容:
1、String s = new String("abc");这句代码究竟创建了几个String对象
这段代码调用的是这样的构造方法:
public String(String original) { //other code …}所以,String s = new String("abc")可以分解为两步:
1 String original = "abc";
2 String s = new String(original );
这样,显然是创建了两个对象。至于String original = "abc"这句代码的原理,String is special中已经讲得很清楚了。
2、public native String intern();
这是一个本地方法。在调用这个方法时,JAVA虚拟机首先检查字符串池中是否已经存在与该对象值相等对象存在,如果有则返回字符串池中对象的引用;如果没有,则先在字符串池中创建一个相同值的String对象,然后再将它的引用返回。
public class StringInternTest {public static void main(String[] args) {// 使用char数组来初始化a,避免在a被创建之前字符串池中已经存在了值为”abcd”的对象 String a = new String(new char[] { ‘a’, ‘b’, ‘c’, ‘d’ }); String b = a.intern(); if (b == a) { System.out.println(“b被加入了字符串池中,没有新建对象”); } else { System.out.println(“b没被加入字符串池中,新建了对象”); } }}运行结果:
b没被加入字符串池中,新建了对象
如果String类的intern()方法在没有找到相同值的对象时,是把当前对象加入字符串池中,然后返回它的引用的话,那么b和a指向的就是同一个对象;否则b指向的对象就是JAVA虚拟机在字符串池中新建的,只是它的值与a相同罢了。上面这段代码的运行结果恰恰印证了这一点。
错误之处,请指正,共同学习,谢过!
- StringBuffer、StringBuilder与String剖析
- String StringBuffer StringBuilder 深度剖析
- String,StringBuffer与StringBuilder
- String,StringBuffer与StringBuilder
- String,StringBuffer与StringBuilder
- String,StringBuffer与StringBuilder
- String, StringBuffer与StringBuilder
- String,StringBuffer与StringBuilder
- String,StringBuffer与StringBuilder
- String、StringBuilder与StringBuffer
- String,StringBuffer与StringBuilder
- String,StringBuffer与StringBuilder
- String 与 StringBuffer/StringBuilder
- String、StringBuffer与StringBuilder
- String与StringBuffer、StringBuilder
- string stringbuffer与stringbuilder
- String,StringBuffer与StringBuilder
- String、StringBuffer与StringBuilder
- Windows Phone 7的XML操作详解:读取,过滤以及数据绑定
- 怎样判断ios app 第一次启动
- MPICH安装后jumpshot未安装的解决方法
- USACO section 1.4.3 Arithmetic Progressions
- iPhone程序包结构
- StringBuffer、StringBuilder与String剖析
- TCO2012Round1B-2-FoxAndDoraemon
- 无刷新对表格的一列排序
- 使用CSS3让文字按指定路径显示
- PHP Mysql Apache 配置
- Qt中Ui名字空间以及setupUi函数的原理和实现
- HDU-1279 模拟
- XCode快捷键
- PowerDesigner中CDM和PDM数据类型的mapping