优先使用字符串字面量而非new string(),因其复用常量池对象,避免堆内存重复分配、减少gc压力,并节省cpu的构造与哈希计算开销;new string()强制堆分配,相同内容仍新建对象,加剧内存占用与gc负担。

回答Java字符串性能优化类面试题,关键不是罗列知识点,而是讲清“为什么这样写更优”——要扣住内存、CPU、GC三个维度,结合JDK版本演进和真实场景。
字符串创建:优先用字面量,慎用 new String()
字面量(String s = "abc")直接走常量池,复用已有对象;new String("abc")一定在堆中新建对象,哪怕内容相同。这多出一次堆分配+一次GC压力。尤其在循环里拼接或解析大量文本时,new String()会快速堆积临时对象。如果必须从byte[]或char[]构建字符串,优先用带编码参数的构造器,避免默认UTF-8触发额外解码开销。
字符串拼接:编译期、运行期分场景选方案
多个字面量拼接(如 "a" + "b" + "c")由JVM在编译期合并为单个常量,零运行时开销;变量参与拼接(如 s1 + s2)在Java 9+由JVM自动翻译为invokedynamic调用,底层委托StringBuilder,效率接近手写;但若拼接逻辑复杂(含条件、循环),仍建议显式用StringBuilder并预估容量(new StringBuilder(128)),避免数组多次扩容复制。
字符串截取与子串:注意 substring 的历史坑
Java 7之前,substring会共享原字符串的char[],导致大字符串被小子串意外持有时无法回收;Java 7起已修复,每次substring都生成独立数组。但仍有隐性成本:每次调用都复制字符数据。若只需校验前缀/后缀(如判断是否以"HTTP/"开头),用startsWith()或regionMatches()比先substring再equals更轻量——它们直接比较原始字节数组,不创建新对象。
重复字符串去重:善用 intern(),但注意JDK版本差异
当系统频繁处理大量重复内容(如日志中的固定状态码、HTTP头名),调用str.intern()可强制归入常量池,后续相同内容复用同一引用,显著降低内存占用。Java 7+后常量池在堆中,intern()只是登记引用,无拷贝开销;但需警惕:常量池除非发生Full GC,否则不主动清理,滥用可能导致堆内存缓慢泄漏。生产环境建议配合弱引用缓存做兜底控制。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











