• 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"

  • 相关阅读:
    13 英寸 MacBook Air 与 MacBook Pro 评比
    [附源码]Python计算机毕业设计SSM教师信息采集系统(程序+LW)
    SAP 电商云 Spartacus UI 的 External Routes 设计明细
    【Redis】事务和锁机制
    YOLOv5全面解析教程①:网络结构逐行代码解读
    2022年朝阳地区新增一所IB世界学校
    mac笔记本当做服务器记录
    【含视频教程】python实现图书管理系统
    27.【C/C++ 最全vector数组的用法 (详解)】
    TCP单进程循环服务器程序与单进程客户端程序
  • 原文地址:https://blog.csdn.net/m0_62436868/article/details/127975556