侧边栏

string/stringBuffer/StringBuilder的区别

string/stringBuffer/StringBuilder的区别
可变性
String 类中使用 final 关键字字符数组保存字符串, private final char value[] ,String 是不可变
而 StringBuilder 与StringBuffer 都继承自 AbstractStringBuilder 类,AbstractStringBuilder中也是使 用字符数组保存字符串 char[]value 但是没有用 final 关键字修饰,
所以这两种对象都是可变的
线程安全性
String 中的对象是不可变的,也就可以理解为常量,线程安全

AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类

StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的

StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。 

性能

  每次对 String 类型进行改变的时候,都会生成一个新的 String 对象
StringBuffer 每次都会对 StringBuffer 对象本身进行操作
相同情况下使用StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
总结:(应用)
操作少量的数据 = String
单线程操作字符串缓冲区下操作大量数据 = StringBuilder-----线程不安全问题
多线程操作字符串缓冲区下操作大量数据 = StringBuffer------线程安全
补充
String类被设计成不可变的原因
总体来说, String不可变的原因包括 设计考虑,效率优化问题,以及安全性这三大方面.
1.字符串常量池的需要
假若字符串对象允许改变,那么将会导致各种逻辑错误,比如改变一个对象会影响到另一个独立对象. 严 格来说,这种常量池的思想,是一种优化手段.
2. 允许String对象缓存HashCode
Java中String对象的哈希码被频繁地使用, 比如在hashMap 等容器中。
字符串不变性保证了hash码的唯一性,因此可以放心地进行缓存.这也是一种性能优化手段,意味着不必 每次都去计算新的哈希码
3. 安全性
String被许多的Java类(库)用来当做参数,例如 网络连接地址URL,文件路径path,还有反射机制所需要 的String参数等, 假若String不是固定不变的,将会引起各种安全隐患
4. 线程安全
因为字符串是不可变的,所以是多线程安全的,同一个字符串实例可以被多个线程共享。这样便不用因 为线程安全问题而使用同步。字符串自己便是线程安全的。

如何实现一个不可变类?
不可变类的设计通常要遵循以下几个原则:
1)将类声明为final,所以它不能被继承。
2)将所有的成员声明为私有的,这样就不允许直接访问这些成员。
3)对变量不要提供setter方法。
4)将所有可变的成员声明为final,这样只能对它们赋值一次。
5)通过构造器初始化所有成员,进行深拷贝(deep copy)。
6)在getter方法中,不要直接返回对象本身,而是克隆对象,并返回对象的拷贝。

posted @ 2019-07-30 14:35  William_lT  阅读(261)  评论(0编辑  收藏  举报