string面试核心在于:对象创建位置(常量池或堆)、内容是否相同(equals)、引用是否一致(==),结合不可变性与内存布局可逻辑推导90%题目。

Java String 面试经典案例,核心不在背答案,而在看清三件事:对象在哪创建(常量池 or 堆)、内容是否相同(equals())、引用是否一致(==)。只要抓住内存位置 + 不可变性这两个支点,90% 的题目都能逻辑自洽地推出来。
一、字面量 vs new String():看清楚“谁在池里,谁在堆里”
这是最基础也最容易混淆的考点。关键不是记结果,而是理解 JVM 的动作:
- String s1 = "abc"; → JVM 查字符串常量池;若无,则新建并放入池中;s1 指向池中地址
- String s2 = new String("abc"); → 先查池(复用已有"abc"),再在堆中 new 出全新 String 对象;s2 指向堆中地址
所以 s1 == s2 一定为 false(地址不同),而 s1.equals(s2) 为 true(内容一样)。
二、编译期拼接 vs 运行时拼接:看表达式能否被编译器提前算出来
Java 编译器会对纯字面量拼接做优化:
-
"a" + "b" + "c" → 编译阶段直接变成 "abc",和
"abc"字面量指向同一个常量池地址 →==成立 -
s1 + "b"(s1 是变量)→ 运行时才执行,底层用 StringBuilder 拼接,结果在堆中 →
==通常为 false
注意:final String s1 = "a"; 是特例——编译器视其为“编译期常量”,s1 + "b" 也会被优化成字面量。
三、intern() 方法:手动把堆对象“拉进”常量池
intern() 的作用是:如果常量池中已有相同内容的字符串,就返回池中引用;否则,把当前字符串内容放入池中,并返回该引用。
- new String("abc").intern() == "abc" → true(因为池中已有"abc",返回池中地址)
- new String("xyz").intern() == "xyz" → true("xyz"首次入池,返回的就是它自己)
这个方法常用于节省内存或统一字符串引用,但要注意 JDK 7+ 后常量池移到堆中,intern() 行为更安全,不会因永久代满而 OOM。
四、不可变性引发的连锁反应:为什么所有“修改”都等于“新建”?
String 类被 final 修饰,内部 value 数组也是 final,且无公开 setter 方法。这意味着:
-
s.concat("x")、s.replace('a','b')、s.substring(1)等操作,全部返回新对象 - 原字符串不受影响,适合多线程共享、作为 HashMap 键、缓存 hash 值
- 频繁修改字符串时,避免用
+循环拼接(每次生成新对象),改用StringBuilder
面试官追问“为什么设计成不可变”,答出线程安全 + 常量池依赖 + 安全哈希这三点,基本就到位了。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











