Android面试-String、StringBuffer 与 StringBuilder 的区别详解

一、三者概览

在 Java 中,String、StringBuffer 和 StringBuilder 都可以用来表示字符串,但它们在可变性、线程安全性和性能上存在明显差异。理解这些差异,是写出高效 Java 代码的基础。

对比项 String StringBuffer StringBuilder
可变性 不可变 可变 可变
线程安全 安全(不可变天然安全) 安全(方法加 synchronized) 不安全
性能 频繁拼接时较差 中等 最高
适用场景 字符串常量、少量操作 多线程环境下的字符串拼接 单线程环境下的字符串拼接

二、String:不可变字符串

String 内部使用 final 修饰的字符数组(JDK 9 之后为 byte[])存储数据,一旦创建就不能被修改。所有看似“修改”的操作,实际上都是创建了一个新的 String 对象。

String s = "hello";
s = s + " world"; // 实际创建了新对象,原对象不变
System.out.println(s); // hello world

由于不可变,String 可以安全地被多个线程共享,也适合作为 HashMap 的 key。但在循环中频繁拼接字符串时,会产生大量临时对象,性能较差。

提示:字符串常量会存放在字符串常量池中,相同字面量会复用同一个对象。

三、StringBuffer:线程安全的可变字符串

StringBuffer 是可变的字符序列,其大部分方法都使用 synchronized 修饰,因此是线程安全的。多个线程同时操作同一个 StringBuffer 对象时不会出现数据错乱。

StringBuffer sb = new StringBuffer();
sb.append("hello");
sb.append(" world");
System.out.println(sb.toString()); // hello world

由于每次操作都需要获取锁,StringBuffer 在单线程场景下的性能不如 StringBuilder。

四、StringBuilder:非线程安全的高性能可变字符串

StringBuilder 与 StringBuffer 的 API 基本一致,但没有加锁,因此在单线程环境下性能更高。它是绝大多数单线程字符串拼接场景的首选。

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++) {
    sb.append(i).append(",");
}
System.out.println(sb.toString()); // 0,1,2,3,4,

五、性能对比示例

下面通过一个简单示例对比三者在循环拼接时的表现:

public class StringTest {
    public static void main(String[] args) {
        int count = 10000;

        long start = System.currentTimeMillis();
        String s = "";
        for (int i = 0; i < count; i++) {
            s += i;
        }
        System.out.println("String: " + (System.currentTimeMillis() - start) + " ms");

        start = System.currentTimeMillis();
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < count; i++) {
            buffer.append(i);
        }
        System.out.println("StringBuffer: " + (System.currentTimeMillis() - start) + " ms");

        start = System.currentTimeMillis();
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < count; i++) {
            builder.append(i);
        }
        System.out.println("StringBuilder: " + (System.currentTimeMillis() - start) + " ms");
    }
}

通常情况下,String 的耗时远高于另外两者,而 StringBuilder 略快于 StringBuffer。

六、如何选择

  • String:字符串内容基本不变,或只是少量拼接、作为常量或 Map 的 key 时使用。
  • StringBuffer:多线程环境下需要频繁修改字符串时使用,保证线程安全。
  • StringBuilder:单线程环境下频繁拼接字符串时使用,性能最佳,是日常开发中最常用的选择。

七、总结

三者的核心区别可以概括为:String 不可变、StringBuffer 可变且线程安全、StringBuilder 可变但非线程安全。实际开发中,优先使用 StringBuilder;只有在明确需要多线程共享同一字符串缓冲区时,才选择 StringBuffer。

使用小程序,查看更多面试题目,随时随地刷题,刷题更方便!

code2

posted @ 2026-11-10 17:10  自由侠  阅读(4)  评论(0)    收藏  举报