string不可变,因其类与内部数组均被final修饰且无修改方法;好处包括安全性、线程安全、常量池复用及哈希值缓存;常量池自jdk7起位于堆内存,字面量自动入池,new创建堆对象并可能触发字面量入池,intern手动入池;==比较地址,equals重写后比较内容。

Java 中 String 相关面试题,核心就三点:理解不可变性、搞懂字符串常量池、分清 == 和 equals 的本质区别。大厂爱考的不是死记硬背,而是你能不能用底层逻辑解释现象。
String 为什么不可变?好处在哪?
String 类被 final 修饰,内部 char[](JDK 8)或 byte[](JDK 9+)也用 final 声明,且没有对外暴露修改方法。一旦创建,内容无法更改——所谓“修改”其实是创建新对象。
- 安全性:作为 HashMap 键、网络请求参数、反射类名等,不可变可避免中途被篡改
- 线程安全:无需同步,多个线程共享同一个 String 实例不会出问题
- 支持字符串常量池优化:只有确定不变,才能放心复用同一份内存
字符串常量池到底存在哪?怎么触发入池?
JDK 7 起,常量池从方法区(永久代)移到堆内存;它不是“所有字符串都自动进池”,而是有明确规则:
- 字面量直接赋值(如 String s = "abc";)一定入池
- new String("abc") 创建两个对象:堆中一个 new 出来的实例 + 字面量 "abc" 入池(如果还没存在)
- 调用 intern() 方法:若池中已有相同内容字符串,返回池中引用;否则将该字符串放入池并返回其引用
例如:new String("ab") + new String("c") 拼接结果不在池中,但 ("ab" + "c").intern() 就会进池。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
== 到底比什么?equals 又为什么能正确比较?
== 比的是引用是否指向同一块内存地址;equals 是 String 重写后的方法,逐字符比较内容。
- String a = "hello"; String b = "hello"; → a == b 为 true(同在常量池,共用地址)
- String c = new String("hello"); → a == c 为 false(c 在堆,a 在池),但 a.equals(c) 为 true
- 自定义类没重写 equals,默认用 Object 的 == 行为;String 已重写,所以安全可靠
常见陷阱题怎么拆解?
遇到类似 “以下代码输出 true 还是 false?” 的题,别急着答,按三步走:
- 看每个字符串是怎么创建的(字面量?new?拼接?)
- 判断哪些进了常量池,哪些在堆,有没有重复引用
- == 看地址,equals 看内容,intern() 看池里有没有再决定返回谁
比如:String s1 = "a" + "b"; String s2 = "ab"; System.out.println(s1 == s2); → true,因为编译期就能确定 "a"+"b" 是常量表达式,直接优化成 "ab" 字面量。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










