• java面试强基(8)


     String、StringBuffer、StringBuilder 的区别?

    可变性

    ​ String 是不可变的。StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串,不过没有使用 final 和 private 关键字修饰,最关键的是这个 AbstractStringBuilder 类还提供了很多修改字符串的方法比如 append 方法。

    String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。

    线程安全性

    ​ String 中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacityappendinsertindexOf 等公共方法。StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。

    性能

    ​ 每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。

    在这方面运行速度快慢为:StringBuilder > StringBuffer > String 

    对于三者使用的总结:

    1. 操作少量的数据: 适用 String
    2. 单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder
    3. 多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer


     

    String 为什么是不可变的? 

    1. 保存字符串的数组被 final 修饰且为私有的,并且String 类没有提供/暴露修改这个字符串的方法。
    2. String 类被 final 修饰导致其不能被继承,进而避免了子类破坏 String 不可变。
    1. String s = "abc"; //(1)
    2. System.out.println("s = " + s);
    3. s = "123"; //(2)
    4. System.out.println("s = " + s);
    1. s = abc
    2. s = 123

    看到这里,你可能对String是不可变对象产生了疑惑,因为从打印结果可以看出,s的值的确改变了。其实不然,因为s只是一个String对象的引用,并不是String对象本身。
    当执行(1)处这行代码之后,会先在方法区的运行时常量池创建一个String对象"abc",然后在Java栈中创建一个String对象的引用s,并让s指向"abc"

  • 相关阅读:
    别再问我Python打包成exe了!(终极版)
    三、博客首页完成《iVX低代码仿CSDN个人博客制作》
    IDEA常用快捷键
    量化风控的规则开发,如何更好做策略定规则,抓坏人
    040几种原生手工封装UUID组件的方案
    Java事务使用@Transactional注解时的几种常见错误
    Java异常try{}catch{}中的return机制
    04-react基础知识-路由
    Java:实现找出字符串中最长的回文子字符串算法(附完整源码)
    IDEA06:Java和Python的进程间通信和心跳包机制
  • 原文地址:https://blog.csdn.net/m0_62436868/article/details/127975556