Java后端面试:核心基础考点,String、StringBuilder、StringBuffer 区别详解
前言
String、StringBuilder、StringBuffer 是Java面试最基础、出场率最高的知识点。大部分面试官都会询问三者区别、底层原理、线程安全以及使用场景。
我整理了一套完整的面试知识点,通俗易懂,适合面试复习,也适合新手巩固Java基础。
一、三者核心区别总结
1.可变性
String:不可变字符串
StringBuilder:可变字符串
StringBuffer:可变字符串
2.线程安全
String:线程安全
StringBuilder:非线程安全
StringBuffer:线程安全
3.性能
String:拼接效率最低
StringBuilder:单线程效率最高
StringBuffer:多线程安全,效率略低
4.适用场景
String:少量字符串定义、静态文本、常量
StringBuilder:单线程环境,大量字符串拼接
StringBuffer:多线程环境,大量字符串拼接
二、底层原理讲解
1.为什么String不可变
String底层使用被final修饰的char数组存储数据,数组一旦初始化完成,无法修改数组地址和内部数据。每次对字符串进行拼接、替换、截取操作,都不会修改原字符串,而是生成一个全新的String对象。
String不可变的优点:
1.可以支持字符串常量池,节省大量内存
2.天然线程安全,多线程共享不会出现数据错乱
3.哈希值固定,非常适合作为HashMap的key
2.StringBuilder和StringBuffer可变原理
两者底层都继承自AbstractStringBuilder,底层使用普通char数组,没有final修饰。拼接字符串时,直接在原数组上修改,不会创建新对象,同时自带数组自动扩容机制,所以拼接性能远高于String。
三、线程安全区别
StringBuffer 的所有 append、修改方法都加入了 synchronized 同步锁,保证多线程并发操作时数据不会丢失、错乱,所以是线程安全的。
StringBuilder 没有任何锁机制,多线程同时拼接字符串会出现覆盖、数据丢失问题,不支持多线程,但是因为没有锁开销,单线程性能最好。
String不可修改,不存在并发修改问题,所以线程安全。
四、开发规范与代码示例
1.不推荐循环内使用String拼接
java |
循环中使用加号拼接,每一次循环都会创建新的字符串对象,产生大量无效垃圾对象,占用内存,GC频繁,性能极差。
2.单线程推荐使用StringBuilder
java |
只会创建一个对象,全程在原数组扩容修改,性能极高,日常开发拼接字符串首选。
3.多线程场景使用StringBuffer
java |
五、面试高频问答
1. String为什么不可变?
底层是final修饰的字符数组,无法修改原有对象。不可变可以保证常量池复用、线程安全、哈希值稳定。
2. StringBuilder和StringBuffer区别?
StringBuffer方法加锁,线程安全但性能低;StringBuilder无锁,线程不安全但性能高。单线程用StringBuilder,多线程用StringBuffer。
3. 循环拼接字符串用什么?
绝对不要用String加号拼接,循环内统一使用StringBuilder,提升程序性能,减少内存占用。
六、总结
1.简单静态字符串直接使用String。
2.所有循环拼接、大量字符串拼接,优先使用StringBuilder。
3.只有多线程共享拼接对象时,才使用StringBuffer。
