JAVA面试:String、StringBuffer和StringBuilder区别

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
性能测试 PTS,5000VUM额度
云原生网关 MSE Higress,422元/月
简介: `String`是不可变的,`StringBuffer`和`StringBuilder`是可变的。`String`的不可变性源于其内部的`final char[]`数组,这意味着每次修改都会创建新对象。`StringBuffer`线程安全,方法同步,适合多线程环境,但效率较低;`StringBuilder`非线程安全,无同步,单线程中效率更高。两者初始容量相同,扩容机制也一样。

 


1. String、StringBuffer和StringBuilder区别

答:String是不可变的,而StringBuffer和StringBuilder是可变的。

这样回答肯定是不满意的,面试官希望听到的是你能说出个为什么?而不是给我一个结论,只说结论面试官会认为你只是背了面试题而已。

2. 为什么String是不可变的?

简单的讲String是内部结构如下

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
...
}

image.gif

是用final char value[]来存储字符串, 所以上不可变的。这么说肯定凉了。

final说明: 修饰的类不能被继承、修饰的方法不能被重写、修饰的基本数据类型变量是其值不能改变、修饰的引用类型变量是不能再指向其他对象。

所以final修饰的char value[],其组据是可变的。

为什么是不可变呢? 先看String的Api,提供了哪些public方法

image.png image.gif image.png

从源码中可以看出

  • String 并没有提供一个可以修改数组值的方法
  • String是final类,不能被继承,也不可能有子类来修改

3.为什么StringBuffer和StringBuilder是可变的?

StringBugger和StringBuilder都继承自AbstractStringBuilder,
StringBugger和StringBuilder存放字符串都放在AbstractStringBuilder的char[] value中。
而AbstractStringBuilder提供如append来修改value的值。所以是可变的。

image.gif

4. StringBuffer和StringBuilder的区别?

1. 先看看源码,如下

image.png

StringBuffer的公开方法加了对象锁,所以是线程安全的,而StringBuilder没有,所以是线程不安全

2. StringBuffer的API加了对象锁,执行速度慢(效率慢)。StringBuilder未加锁,执行速度快(效率高)。

3. toString方法不同,直接看源码

image.png

注: toStringCache的定义是 private transient char[] toStringCache

从源码看出:

  • StringBuffer的toString都会直接使用缓存区的toStringCache值来构造一个字符串
  • 而StringBuilder是需要复制一次字符数组,再构造一个字符串

5. StringBuffer和StringBuilder相同之处?

  1. 字符串都可变
  2. 默认初始容量都是16
  3. 扩容机制相同。源码如下:
都是调父类AbstractStringBuilder 的扩容方法,源码如下:
    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }
    private int newCapacity(int minCapacity) {
        // overflow-conscious code
        int newCapacity = (value.length << 1) + 2;
        if (newCapacity - minCapacity < 0) {
            newCapacity = minCapacity;
        }
        return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
            ? hugeCapacity(minCapacity)
            : newCapacity;
    }
    private int hugeCapacity(int minCapacity) {
        if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
            throw new OutOfMemoryError();
        }
        return (minCapacity > MAX_ARRAY_SIZE)
            ? minCapacity : MAX_ARRAY_SIZE;
    }

image.gif


相关文章
|
13天前
|
安全 Java
Java基础之StringBuffer
【7月更文挑战第1天】 Java中的`StringBuffer`是线程安全的字符串操作类,适合多线程环境,而`StringBuilder`非线程安全,速度更快,适用于单线程。两者提供`append()`、`insert()`、`delete()`等方法修改字符串,避免了频繁创建新对象的性能问题。在不需要线程安全时,推荐使用`StringBuilder`以提高效率。
12 1
|
14天前
|
安全 Java 索引
带你快速掌握Java中的String类和StringBuffer类(详解常用方法 | 区别 )
带你快速掌握Java中的String类和StringBuffer类(详解常用方法 | 区别 )
|
18天前
|
存储 Java API
Java基础之String类
Java的String类是引用类型,用于创建和操作字符串。字符串对象在`java.lang`包中,不可变。创建方式包括字面量和`new`关键字。字符串池存储字符串常量,避免重复。比较字符串用`equals()`(区分大小写)和`equalsIgnoreCase()`(不区分大小写)。`length()`返回长度,`concat()`或`+`拼接,`substring()`截取,`indexOf()`和`lastIndexOf()`查找,`replace()`替换,`split()`分割。这些是常用的字符串API。
10 0
|
18天前
|
Java
Java基础之String类
Java基础之String类
15 0
|
20天前
|
存储 缓存 安全
java源码之String详解
java源码之String详解
15 0
|
22天前
|
Java UED
Java中String强转int:一种常见的错误和解决方法
在Java中将非数字字符串转换为整数会导致`NumberFormatException`。要解决这个问题,可以使用`try-catch`捕获异常,正则表达式验证数字格式,或利用异常信息提供错误提示。例如,`Integer.parseInt()`会因遇到非数字字符如`&quot;123abc&quot;`而抛出异常,但通过异常处理或正则`\\d+`可确保安全转换。记得在编程时避免直接强转,以防止程序异常中断。
|
1月前
|
Java 安全 索引
滚雪球学Java(48):面向对象编程中的StringBuffer类详解
【6月更文挑战第2天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
33 5
滚雪球学Java(48):面向对象编程中的StringBuffer类详解
|
21天前
|
Java 数据处理 Apache
探讨Java中判断String类型为空和null的方法
探讨Java中判断String类型为空和null的方法
14 1
|
1月前
|
存储 Java 测试技术
滚雪球学Java(47):String类教程:如何在Java中使用字符串操作
【6月更文挑战第1天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
26 2
滚雪球学Java(47):String类教程:如何在Java中使用字符串操作
|
24天前
|
Java API 索引
java中String类常用API
java中String类常用API

热门文章

最新文章

  • 1
    @SneakyThrows 是 Lombok 库中的一个注解
    5
  • 2
    在会议系统工程中,Python可以用于多种任务,如网络请求(用于视频会议的连接和会议数据的传输)、数据分析(用于分析会议参与者的行为或会议效果)等。
    9
  • 3
    在可视会议系统工程中,系统工程方法可以帮助我们系统地规划、设计和实现一个高效、可靠的可视会议系统。
    10
  • 4
    我们可以从系统工程的角度来讨论如何优化组织架构,并给出一些可能涉及的Python应用领域的示例。
    7
  • 5
    在环境治理领域,污染治理系统工程旨在通过系统的方法来解决环境污染问题。这通常包括污染源的识别、污染物的监测、治理技术的选择、治理效果的评估等多个环节。
    14
  • 6
    我将提供一个简化的Python代码示例和详解,以展示如何使用Python和Django框架来构建智能化小区综合物业管理系统的一部分功能。
    8
  • 7
    在系统工程中,软件测试是一个至关重要的环节,它确保软件的质量、可靠性和性能。软件测试通常包括多个阶段,如单元测试、集成测试、系统测试和验收测试等。
    14
  • 8
    在软件部署阶段,系统工程的目标是确保软件能够顺利、稳定地部署到目标环境中,并满足用户的需求。
    11
  • 9
    航空航天领域,系统工程被用于设计复杂的飞行器和系统。这包括飞行器的结构、推进系统、控制系统等。
    12
  • 10
    在通讯系统工程中,这通常包括硬件、软件、网络协议、数据传输等多个方面的设计和实现。
    9