java字符串拼接底层分编译期优化与运行期创建:字面量拼接(如"a"+"b")在编译期折叠为常量池中单个字符串;含变量则编译为stringbuilder.append().tostring(),每次执行新建对象。

面试官问“Java字符串拼接底层实现”,不是想听你背概念,而是考察你是否真正理解 编译期优化 和 运行时对象创建逻辑 这两个关键分水岭。
看有没有区分“常量拼接”和“变量拼接”
这是最核心的判断点。如果候选人只说“+就是用StringBuilder”,说明没深入过字节码。
- 两个或多个字面量直接拼接(如
"a" + "b" + "c"):编译器在javac阶段就合并成一个字符串字面量,存入常量池,运行时无额外对象 - 只要有一个变量参与(如
s1 + "b"或s1 + s2):编译后生成StringBuilder.append()调用,每次拼接都新建 StringBuilder 实例(JDK8及以前),再调用toString()创建新 String 对象
看懂字节码才是硬核证据
真正懂的人会提到 javap -v 反编译结果:
- 常量拼接的 class 文件常量池里,只有合并后的字符串(如
#21 = Utf8 ab),没有单独的a和b - 变量拼接的 class 文件里,会出现
StringBuilder的构造、append、toString三条方法调用指令
能否联系内存与性能影响
不能只停留在“用了StringBuilder”,要说出后果:
- 循环中用
+拼接(如for里result += str):每轮都 new StringBuilder → new String,产生大量临时对象,GC压力大 - 推荐替代方案:显式用
StringBuilder(单线程)或StringBuffer(多线程),预估容量避免频繁扩容 - JDK8+ 的
String.join()或String.formatted()在特定场景更简洁安全
是否意识到 String 不可变性与拼接的逻辑自洽
很多人知道“String不可变”,但没想通为什么还能拼接:
- 拼接不是修改原对象,而是创建新对象;不可变性保障了常量池复用和线程安全
-
new String("abc")一定在堆新建对象,而"abc"优先从常量池取;intern()可手动触发入池 - 面试中若被问
s1 == s2结果,必须结合“谁在常量池、谁在堆”来答,不能只说“看地址”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











