首页 > 代码库 > Java中String、StringBuffer和StringBuilder比较
Java中String、StringBuffer和StringBuilder比较
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6581009.html
在编程中,对于字符串拼接,我们可以用String类重载的+或concat(str)、StringBuffer的append(str)、StringBuilder的append(str)。那么,三者到底有什么不同呢?
一:String
1:String类的特性
1)String是个final类:所以String类是不可以被继承的。同样,String对象的值是不可以被改变的;
2)String对象的创建方法比较(原理比较):
在JVM加载运行class文件时,对于字节文件中出现的常量(符号引用、字符串字面量等)会在方法区的常量池中分类存放。其中,源代码中出现过的字符串字面常量会保存在 CONSTANT_String_info常量表中。然后,根据不同的创建方法,会有不同的内容分配,具体如下:
1、字面常量方式创建String变量:String str1=“string” ;
String str2="string";
上面创建了两个String引用,都指向同样内容的字符串。我们知道该类在加载时,字符串常量被存放在 CONSTANT_String_info常量表 中,并且同一字符串内容只会存放一次(我们称常量表中的字符串为“拘留字符串”)。故此,上面两个String引用都指向 CONSTANT_String_info常量表 中的同一地址(同一拘留字符串)。因此,这里 str1==str2 返回true。(另:这里是没有创建string对象的,因为没有在堆中分配内存)
2、通过new关键字创建String对象:String str1=new String("string");
String str2=new String("string");
类在加载时,首先把源代码中出现的字符串常量放在CONSTANT_String_info常量表中,故此:上面两语句中相同的 “string” 常量值放在了字符串常量表中同一处。然后,在执行到这两条语句时,根据new关键字,在堆中分别创建String对象str1和str2,并且两对象在堆中保存值均为 "string" 。也就是说,此时JVM中有三个地方存有同一字符串值:常量表中的拘留字符串、str1对象的堆空间、str2对象的堆空间。因此,这里的 str1==str2 返回的是false。调用String类重写过的equals()方法比较两对象的值才返回true。
3、通过intern()方法创建的String“对象”:String str1="string";
String str2=new String("string").intern();
intern()的作用:当常量池的字符串常量表中存在与 "string" 相同(内容相同)的字符串(拘留字符串)时,则直接返回这个拘留字符串的地址,赋值给str2(此时没有创建新的对象);
如果常量池中没有与 “string” 相同的拘留字符串时,则把 "string" 添加到常量池中(成为拘留字符串,供下一个intern()时作返回用),并在堆中创建String对象然后把对象的引用返回(此时有新对象创建);
因此,这里 str1==str2 返回true。
由此可见,intern()方法主要可以用来避免创建内容重复的String对象,值得我们重视。
2:String中重载的 + 和 concat(str) 工作原理
二:StringBuffer
1:StringBuffer是个线程安全的final类
2:StringBuffer的 append() 工作原理
三:StringBuilder
1:StringBuilder是个非线程安全的final类
2:StringBuilder的append() 工作原理
四:三者性能比较与选用
1:性能
2:不同情景下的选用
Java中String、StringBuffer和StringBuilder比较