java string面试核心在于理清常量池、堆内存、==与equals区别及不可变性:字面量复用常量池(a==b为true),new创建堆对象(c==d为false),intern()确保返回常量池引用(s2==s3为true),concat等操作不修改原串,多线程拼接须用stringbuffer。

Java 中 String 相关面试题容易出错,核心在于没理清 字符串常量池、堆内存、引用比较与内容比较的区别,以及 String 不可变性带来的连锁影响。改错不是背答案,而是重建对底层机制的理解。
错题典型:== 和 equals 混用
常见错误写法:
String a = "hello";String b = "hello";
System.out.println(a == b); // true —— 误以为“碰巧对”,其实有原理
更危险的错误:
String c = new String("hello");String d = new String("hello");
System.out.println(c == d); // false —— 误以为“都是 hello 就该相等”
✅ 正确理解:
-
==比较的是引用是否指向同一块内存地址 -
equals()比较的是字符串内容是否相同(String 重写了 equals) -
"hello"字面量会进入字符串常量池,重复字面量复用同一对象 →a == b为 true -
new String("hello")总是在堆中新建对象,即使内容一样,地址也不同 →c == d为 false
错题典型:intern() 的作用被忽略
比如这道题常被答错:
String s1 = new String("abc");String s2 = s1.intern();
String s3 = "abc";
System.out.println(s2 == s3); // true?false?
✅ 正确逻辑:
-
s1是堆中对象,不在常量池 -
s1.intern()会检查常量池:若无"abc",则将堆中s1的字符内容放入池中,并返回池中引用;若有(如s3已存在),直接返回池中已有引用 -
s3 = "abc"从常量池取,s2也是常量池引用 →s2 == s3为 true(JDK7+)
错题典型:认为 String 可变或修改了原串
典型误解代码:
String s = "ab";s.concat("c");
System.out.println(s); // 输出 "ab" —— 有人误以为变成 "abc"
✅ 关键点:
- String 是不可变(immutable)的:所有看似“修改”的方法(
concat、substring、replace等)都返回新对象 - 原引用
s仍指向旧字符串,必须重新赋值才生效:s = s.concat("c"); - 不可变性带来线程安全和常量池优化,但频繁拼接要用
StringBuilder
错题典型:混淆 StringBuilder 和 StringBuffer
比如问“多线程环境下拼接字符串该用哪个”,答“StringBuilder”就错了。
✅ 区别清晰化:
-
StringBuilder:非线程安全,性能高,日常单线程场景首选 -
StringBuffer:方法加了synchronized,线程安全,但开销大 - 二者都不共享内部 char[],所以不存在“多个线程操作同一个 StringBuilder 实例”的安全问题——但若多个线程共用同一实例且无同步,结果不可预测
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











