String-StringBuffer-StringBuilder

String类为什么是不可变的?StringBuilder和StringBuffer的区别,字符串常量池,StringBuffer为什么线程安全?加号的底层原理?

String类为什么是不可变的
  • String不可变的原因包括 设计考虑,效率优化问题,以及安全性这三大方面。

  • 安全性:String被许多的Java类(库)用来当作参数,例如:网络连接地址URL,文件地址path…假若String不是固定不变的,将会引起各种安全隐患

  • 优化:Java中String对象的哈希码被频繁地使用, 比如在hashMap 等容器中。

    字符串不变性保证了hash码的唯一性,因此可以放心地进行缓存.这也是一种性能优化手段,意味着不必每次都去计算新的哈希码. 在String类的定义中有如下代码:

    private int hash;// 用来缓存hashCode
    
  • 优化:字符串常量池(String pool, String intern pool, String保留池) 是Java堆内存中一个特殊的存储区域, 当创建一个String对象时,假如此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已经存在的对象。

StringBuilder和StringBuffer的区别
  • StringBuilder是非线程安全的,StringBuffer是线程安全的

(即使碰到了需要线程安全的情景,也没必要用StringBuffer,因为stringbuffer的线程安全,仅仅是保证jvm不抛出异常顺利的往下执行而已,它可不保证逻辑正确和调用顺序正确。大多数时候,我们需要的不仅仅是线程安全,而是锁。)

字符串常量池
  • 字符串常量池的设计思想

    1. 字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建字符串,极大程度地影响程序的性能

    2. JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化。

      为字符串开辟一个字符串常量池,类似于缓存区。

      创建字符串常量时,首先查看字符串常量池是否存在该字符串。

      存在该字符串,返回引用实例,不存在,实例化该字符串并放入池。

    3. 实现的基础

      实现该优化的基础是因为字符串是不可变的,可以不用担心数据冲突进行共享。

      运行时实例创建的全局字符串常量池中有一个表,总是为池中每个唯一的字符串对象维护一个引用,这就意味着它们一直引用着字符串常量池中的对象,所以,在常量池中的这些字符串不会被垃圾收集器回收。

  • 通过new操作符创建的字符串对象不指向字符串池中的任何对象,但是可以通过使用字符串的intern()方法来指向其中的某一个。

String s1 = "Hello";
String s2 = new StringBuffer("He").append("llo").toString();
String s3 = s2.intern();
StringBuffer为什么线程安全
  • 首先String的不可变的,所以线程安全

  • StringBuffer和StringBuilder是可变的,但是StringBuffer的append操作是带有synchronized的,所以线程安全。

    https://juejin.im/post/5ae6dc04f265da0ba351d3ff—synchronized详解

加号的底层原理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值