最快见效的方式是直接练真题、盯内存、动手验证;关键在于理解字符串创建位置、引用指向、==与equals差异,紧扣常量池与堆的创建逻辑,结合反编译和intern()深入掌握。

直接练真题、盯内存、动手验证,是最快见效的方式。光看理论容易绕晕,关键在理解字符串对象在哪创建、引用怎么走、== 和 equals 为什么结果不同。
紧扣常量池和堆的创建逻辑
面试最爱考“创建几个对象”,本质是考你是否清楚字面量和 new 的区别、编译期优化是否生效:
-
字面量赋值(如
String s = "abc"):只查常量池,有就复用,没就新建并入池 - new String("abc"):一定在堆新建对象;若常量池无"abc",还会额外在池中建一个——共两个对象
-
拼接含变量(如
String s = str1 + "c"):JVM 编译后转成 StringBuilder.append,结果对象在堆里,不进常量池 -
纯字面量拼接(如
"a" + "b"):编译期直接优化为"ab",等价于字面量,只进常量池
动手反编译验证,别信“好像”
很多争议题(比如 new String("a") + new String("b") 创建几个对象),靠背结论容易错。正确做法是:
- 写好代码,用
javac编译成 class 文件 - 运行
javap -verbose Xxx.class查看常量池内容和字节码指令 - 重点关注
ldc(从常量池加载)、new(堆上新建)、invokespecial(调用构造方法)这些指令出现次数
重点对比 == 和 equals 的实际行为
这不是语法题,是内存模型题。每次写完比较,立刻想清楚两边引用指向哪:
-
s1 == s2成立,仅当二者指向同一块内存(同在常量池 / 同为堆中同一对象) -
s1.equals(s2)只比内容,不管在哪,但要注意 null 安全(建议用Objects.equals(s1, s2)) - 典型陷阱:
new String("abc").equals("abc")是 true;new String("abc") == "abc"是 false
结合 intern() 理解池与堆的桥梁作用
intern() 是打破“堆对象无法进池”的关键操作,常用于节省内存或统一引用:
-
String s = new String("hello").intern();→ 强制让这个堆对象“登记”进常量池,后续再用"hello"就会复用它 - 注意 JDK 7+ 后,
intern()不再复制字符串,而是把堆对象的引用存入常量池(池里存的是引用,不是副本) - 可用来验证:执行
s.intern() == "hello"在多数情况下返回 true
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











