其实只要找下Google大神就有答案了:StringBuffer 与 StringBuilder 中的方法和功能完全是等价的,只是StringBuffer 中的方法大都采用了 synchronized 关键字进行修饰,因此是线程安全的,而 StringBuilder 没有这个修饰,可以被认为是线程不安全的。 
 
为了更好的理解上述的答案,还是直接看StringBuffer与StringBuilder的源码实现比较实在,作为一个程序猿,“有疑问,看源码”才是正道,我可以负责任的说,当然了得有条件才行!
 
jdk的实现中StringBuffer与StringBuilder都继承自AbstractStringBuilder,对于多线程的安全与非安全看到StringBuffer中方法前面的一堆synchronized就大概了解了。
 
这里随便讲讲AbstractStringBuilder的实现原理:我们知道使用StringBuffer等无非就是为了提高java中字符串连接的效率,因为直接使用+进行字符串连接的话,jvm会创建多个String对象,因此造成一定的开销。AbstractStringBuilder中采用一个char数组来保存需要append的字符串,char数组有一个初始大小,当append的字符串长度超过当前char数组容量时,则对char数组进行动态扩展,也即重新申请一段更大的内存空间,然后将当前char数组拷贝到新的位置,因为重新分配内存并拷贝的开销比较大,所以每次重新申请内存空间都是采用申请大于当前需要的内存空间的方式,这里是2倍。
 
 
接下来,玩些好玩的!
在Google中出来了这么一些信息:
 
    StringBuffer 始于 JDK 1.0 
    StringBuilder 始于 JDK 1.5

从 JDK 1.5 开始,带有字符串变量的连接操作(+),JVM 内部采用的是 
    StringBuilder 来实现的,而之前这个操作是采用 StringBuffer 实现的。

 
我们通过一个简单的程序来看其执行的流程:
 
清单1 Buffer.java
  1. public class Buffer {
  2. public static void main(String[] args) {
  3. String s1 = "aaaaa";
  4. String s2 = "bbbbb";
  5. String r = null;
  6. int i = 3694;
  7. r = s1 + i + s2;
  8. for(int j=0;i<10;j++){
  9. r+="23124";
  10. }
  11. }
  12. }
 
使用命令javap -c Buffer查看其字节码实现:
 
清单2 Buffer类字节码
 
将清单1和清单2对应起来看,清单2的字节码中ldc指令即从常量池中加载“aaaaa”字符串到栈顶,istore_1将“aaaaa”存到变量1中,后面的一样,sipush是将一个短整型常量值(-32768~32767)推送至栈顶,这里是常量“3694”,更多的Java指令集请查看另一篇文章“Java指令集”。
 
让我们直接看到13,13~17是new了一个StringBuffer对象并调用其初始化方法,20~21则是先通过aload_1将变量1压到栈顶,前面说过变量1放的就是字符串常量“aaaaa”,接着通过指令invokevirtual调用StringBuffer的append方法将“aaaaa”拼接起来,后续的24~30同理。最后在33调用StringBuffer的toString函数获得String结果并通过astore存到变量3中。
 
看到这里可能有人会说,“既然JVM内部采用了StringBuffer来连接字符串了,那么我们自己就不用用StringBuffer,直接用”+“就行了吧!“。是么?当然不是了。俗话说”存在既有它的理由”,让我们继续看后面的循环对应的字节码。
 
37~42都是进入for循环前的一些准备工作,37,38是将j置为1。44这里通过if_icmpge将j与10进行比较,如果j大于10则直接跳转到73,也即return语句退出函数;否则进入循环,也即47~66的字节码。这里我们只需看47到51就知道为什么我们要在代码中自己使用StringBuffer来处理字符串的连接了,因为每次执行“+”操作时jvm都要new一个StringBuffer对象来处理字符串的连接,这在涉及很多的字符串连接操作时开销会很大。

StringBuffer与StringBuilder原理与区别的更多相关文章

  1. StringBuffer与StringBuilder有什么区别

    package String比较; /* * StringBuffer与StringBuilder有什么区别 * StringBuilder是JDK5增加的一个新类,功能几乎与StringBuffer ...

  2. Java基础(四) StringBuffer、StringBuilder原理浅析

    StringBuilder与StringBuffer作用就是用来处理字符串,但String类本身也具备很多方法可以用来处理字符串,那么为什么还要引入这两个类呢? 关于String的讲解请看Java基础 ...

  3. String与StringBuffer和StringBuilder的根本区别(String为什么无法修改字符串长度)

    从网上看了很多的信息,说的大部分是关于final修饰的原因,却没有详细的解释!根据自己收集的资料,跟大家分享一下我的观点(有错请指正).1.我们都知道在修改字符串长度的时候,StringBuffer和 ...

  4. String、StringBuffer、StringBuilder之间的区别

    String                      字符串常量 StringBuffer         字符串变量(线程安全) StringBuilder       字符串变量(非线程安全) ...

  5. String、StringBuffer和StringBuilder类的区别

    Java提供了String.StringBuffer和StringBuilder类来封装字符串,并提供了一系列操作字符串对象的方法. 它们的相同点是都用来封装字符串:都实现了CharSequence接 ...

  6. Java基础知识(JAVA中String、StringBuffer、StringBuilder类的区别)

    java中String.StringBuffer.StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题.现在总结一下,看看他们的不同与相同. 1.可变与不可 ...

  7. Java String、StringBuffer、StringBuilder有什么区别

    ① String是Java语言非常基础和重要的类,提供了构造和管理字符串的各种基本逻辑.它是典型的immutable类,被声明成final class,所有属性也都是final的,由于它的不可变性,类 ...

  8. String、Stringbuffer和Stringbuilder之间的区别

    关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺点,到底什么时候该用谁呢?下面我们从以下几点说明一下 1.在执行速度方面:Stringbuilder>Stringbuffer&g ...

  9. Java基础 StringBuffer、StringBuilder原理浅析

    StringBuilder与StringBuffer作用就是用来处理字符串,但String类本身也具备很多方法可以用来处理字符串,那么为什么还要引入这两个类呢? 首先看下面的例子 public sta ...

随机推荐

  1. TCP连接的建立与关闭

    TCP是主机对主机层的传输控制协议:建立连接要三个握手,断开连接要四次挥手. 位码即TCP标志位,有6种标示:SYN(synchronous建立联机),ACK(acknowledgement 确认), ...

  2. Flex学习第一天(两个数相加)

    <?xml version="1.0" encoding="utf-8"?><s:Application xmlns:fx="htt ...

  3. Swift基础学习01

    相关网站:http://www.cnblogs.com/tt_mc/p/3871295.html   相关辅助操作: 可以在右边直接查看输出值   可能出现的常见问题: 1.凡是=注意左右间距一样 2 ...

  4. 关于SWT中的Label类和Text类

    Label类的继承关系图 Label是SWT中最简单的界面组件,给出他的一个实例如下: public class Label1 { public static void main(String[] a ...

  5. matlab的legend用法

    用Matlab画图时,有时候需要对各种图标进行标注,例如,用“+”代表A的运动情况,“*”代表B的运动情况. legend函数的基本用法是: LEGEND(string1,string2,string ...

  6. I2C总线协议的总结介绍

    在看天翔哥的视频之后,他强调要把I2C协议好好研究一下,那么就对一些基本的通信手段是十分有帮助的..那么就来了解一下I2C总线协议的一些知识吧. I2C(Inter-Integrated Circui ...

  7. 在centos中php 在连接mysql的时候,出现Can't connect to MySQL server on 'XXX' (13)

    原文连接:http://hi.baidu.com/zwfec/item/64ef5ed9bf1cb3feca0c397c 红色的是命令 SQLSTATE[HY000] [2003] Can't con ...

  8. 【转】spring - ioc和aop

    [转]spring - ioc和aop 1.程序中为什么会用到spring的ioc和aop 2.什么是IOC,AOP,以及使用它们的好处,即详细回答了第一个问题 3.原理 关于1: a:我们平常使用对 ...

  9. 牛客OJ——[编程题]A+B和C__如何输入多组测试数据(测试OK)

    几个要注意的地方: (1)Java OJ,必须将类名写成Main (2)关于如何输入多组测试数据,用二维数组去存储是一个方法,直接在while里面做也可以          但是如果  (3)关于整形 ...

  10. 使用info.plist(或工程名-info.plist)向程序中添加软件Build ID或者版本号信息

    在实际应用程序开发过程中,经常需要向程序中添加软件版本号或者类似的信息,以保证之后发现问题时知道bug所在的版本,我们可以通过在工程名-info.plist文件中设置相关的key/value对(键/值 ...