JAVA面试:String、StringBuffer和StringBuilder区别

本文涉及的产品
应用实时监控服务-用户体验监控,每月100OCU免费额度
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
可观测可视化 Grafana 版,10个用户账号 1个月
简介: `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


相关文章
|
18天前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
1月前
|
安全 Java 测试技术
Java零基础-StringBuffer 类详解
【10月更文挑战第9天】Java零基础教学篇,手把手实践教学!
25 2
|
25天前
|
存储 安全 Java
String、StringBuffer 和 StringBuilder 的区别
【10月更文挑战第21天】String、StringBuffer 和 StringBuilder 都有各自的特点和适用场景。了解它们之间的区别,可以帮助我们在编程中更合理地选择和使用这些类,从而提高程序的性能和质量。还可以结合具体的代码示例和实际应用场景,进一步深入分析它们的性能差异和使用技巧,使对它们的理解更加全面和深入。
15 0
|
1月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
119 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
1月前
|
前端开发 小程序 JavaScript
面试官:px、em、rem、vw、rpx 之间有什么区别?
面试官:px、em、rem、vw、rpx 之间有什么区别?
43 0
|
6月前
|
安全 Java
Java StringBuffer 和 StringBuilder 类
Java StringBuffer 和 StringBuilder 类
47 0
|
6月前
|
存储 XML 缓存
Java字符串内幕:String、StringBuffer和StringBuilder的奥秘
Java字符串内幕:String、StringBuffer和StringBuilder的奥秘
69 0
|
3月前
|
安全 Java API
Java系类 之 String、StringBuffer和StringBuilder类的区别
这篇文章讨论了Java中`String`、`StringBuffer`和`StringBuilder`三个类的区别,其中`String`是不可变的,而`StringBuffer`是线程安全的可变字符串类,`StringBuilder`是非线程安全的可变字符串类,通常在单线程环境下性能更优。
Java系类 之 String、StringBuffer和StringBuilder类的区别
|
3月前
|
安全 Java
【Java基础面试二十七】、说一说StringBuffer和StringBuilder有什么区别
这篇文章介绍了Java中StringBuffer和StringBuilder的区别:StringBuffer是线程安全的,而StringBuilder是非线程安全的,因此在单线程环境下优先推荐使用StringBuilder以获得更好的性能。
|
3月前
|
API C# 开发者
WPF图形绘制大师指南:GDI+与Direct2D完美融合,带你玩转高性能图形处理秘籍!
【8月更文挑战第31天】GDI+与Direct2D的结合为WPF图形绘制提供了强大的工具集。通过合理地使用这两种技术,开发者可以创造出性能优异且视觉效果丰富的WPF应用程序。在实际应用中,开发者应根据项目需求和技术背景,权衡利弊,选择最合适的技术方案。
150 0