String、StringBuffer、StringBuilder的区别及使用
不可变类 - String
一如既往,在进行学习之前我们先看看相关的定义吧~下面引自 JavaDocs:
Strings are constant; their values cannot be changed after they are created
String 类是不可变的,String 对象的值在创建后不会发生改变。换句话说,我们平常对 String 对象的操作,实际上都是创建了一个新的 String 对象,将该对象的引用赋给我们的对象,而内存之中仍然存有原来的两个字符串。可能有点绕,大家可以看看下面的代码:
public class Demo { public static void main(String[] args) { String str; String changeStr; str = "chaos"; changeStr = ""; System.out.println("初始"); System.out.println(str); System.out.println(changeStr); changeStr = change(str); System.out.println("改变后"); System.out.println(changeStr); System.out.println(str); } private static String change(String str){ str = str + "change"; return str; } }输出:初始
chaos改变后
chaoschange
chaos我们可以看到,change() 方法并没有改变 test 的值。为什么呢?因为实际上,传给 change() 方法的是引用的一个拷贝,原对象并没有作为参数被方法修改。所以 String 具有一个大坑:如果我们没有注意到 String 类的这个特性,将多个频繁发生改变的字符串的对象类型选为 String的话,内存一定会受此影响,从而影响系统性能;此外,当引用过多,还会出发垃圾回收机制,影响性能。
线程安全的 StringBuffer
A thread-safe, mutable sequence of characters. A string buffer is like a String, but can be modified.
StringBuffer 和 String 的最大区别在于,StringBuffer 是一个可变类,换句话说,StringBuffer 中的值不但可以改变,还不会产生 String 类的副作用(不断创建对象)。此外,StringBuffer 还是线程安全的。例如:
public class Demo { public static void main(String[] args) { String str; StringBuffer sb = new StringBuffer(); StringBuffer changeSb = new StringBuffer(); str = "chaos"; sb.append(str); System.out.println("初始"); System.out.println(sb.toString()); changeSb = sb; changeSb.append("change"); System.out.println("改变后"); System.out.println(sb.toString()); System.out.println(changeSb.toString()); } }输出:初始
chaos
改变后
chaoschange
chaoschange所以如果我们的程序中如果存在需要频繁修改值的字符串,最好是使用 StringBuffer,因为除了刚刚提到的“线程安全”和“可变”两个特性以外,每个 StringBuffer 还具有一定的缓冲区容量,只有当字符串大小超过容量上限才会增加容量大小。那么这样看下来,很多人会觉得 StringBuffer 很完美,以后就用它了!对于这样的同学我想说一句:且慢!!!事实上,StringBuffer 虽然看起来很完美,但它的线程安全实现机制是它最大的弱点,我们先来看看它是怎么实现线程安全的:
@Override public synchronized StringBuffer append(boolean b) { toStringCache = null; super.append(b); return this; }我们可以看到,StringBuffer 通过 synchronized 关键字为方法加上同步锁,从而实现线程安全。但如果我们 append 1w 次,那么程序就要负担 1w 次加锁解锁带来的时间消耗,影响了效率。此外,大部分情况下,我们都是在单线程情况下使用 String,不需要考虑到线程安全问题,这就使得 StringBuffer 的加锁/解锁过程为程序带来了不必要的开支。所以在 Effective Java 中就有这么一句话:
Java 1.5发行版本中增加了非同步 StringBuilder 类,代替了现在已经过时的 StringBuffer 类
非线程安全的 StringBuilder
事实上,StringBuilder 的内部实现和 StringBuffer 几乎一样,唯一的区别在于:StringBuilder 中去掉了 synchronized 关键字,失去了线程安全的特性。我们刚刚也提到了,StringBuffer 的线程安全机制在大多数情况下都不必要,为系统带来的开销完全是不必要的,所以 Java 1.5 发行版本推出了 StringBuilder。其他方面倒没什么区别,所以最佳方案应该是使用 StringBuilder,如果需要考虑线程安全问题,再考虑 StringBuffer,或者重写 StringBuilder 的相应方法实现线程安全。
转自http://blog.csdn.net/u012403246/article/details/45787585
- String、StringBuffer、StringBuilder区别及使用场合
- Java:String、StringBuffer和StringBuilder的区别与使用。
- 深入理解String类型、StringBuilder、StringBuffer的区别与使用
- Java中的String,StringBuilder,StringBuffer三者的区别和各自使用方法
- Java中String,StringBuffer,StringBuilder的区别及其使用
- String、StringBuffer和StringBuilder使用和区别
- String、StringBuffer、StringBuilder主要区别及使用选择
- java中String、StringBuffer、StringBuilder的区别及StringBuilder的使用
- String、StringBuffer和StringBuilder区别以及使用条件
- java中String、StringBuffer、StringBuilder的区别 java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,他们之间的区
- java中的StringBuilder类的使用, String、StringBuilder、StringBuffer的区别
- String,StringBuilder和StringBuffer区别及使用场景
- String,StringBuffer,StringBuilder之间的区别,以及使用中该注意什么(转)
- Java关键字系列 — String、StringBuffer、StringBuilder的区别和使用
- String,StringBuffer,StringBuilder的区别及使用
- String、StringBuffer、StringBuilder的区别和使用环境
- String, StringBuffer, StringBuilder三者的使用和区别
- java字符串(1):String,StringBuffer,StringBuilder的使用与区别
- String、StringBuffer和StringBuilder的区别以及使用方法
- String、StringBuffer、StringBuilder的区别及使用