目录
情况1:String s1 = "abc"; String s2 = "abc";
情况2:String s1 = new String("abc"); String s2 = new String("abc");
摘要:
String内存机制主要分三种情况:
1)字面量赋值时,相同字符串共享常量池地址(s1==s2为true);
2)new创建时,每次都在堆生成新对象(s1==s2为false);
3)编译期优化会合并字面量拼接。
关键结论:
==比较栈地址,字面量入常量池共享,new必定新建对象。
字符串内容比较必须用equals(),其实现会依次检查对象同一性、类型和字符内容。
面试重点在于理解常量池机制和对象创建方式的差异。
String 内存完整流程(面试必考,纯严谨结构)
我们分三种最典型情况,直接画内存,不绕弯。
情况1:String s1 = "abc"; String s2 = "abc";
【虚拟机栈】s1 → 地址 0x0011s2 → 地址 0x0011【堆】0x0011: String 对象,内容 "abc"【字符串常量池】"abc" → 指向堆中 0x0011
执行 s1 == s2
- 比较栈中存储的地址:0x0011 == 0x0011
- 结果:true
情况2:String s1 = new String("abc"); String s2 = new String("abc");
【虚拟机栈】s1 → 地址 0x0011s2 → 地址 0x0022【堆】0x0011: String 对象,内容 "abc"0x0022: String 对象,内容 "abc"【字符串常量池】"abc" 存在,但两个 new 都会新建堆对象
执行 s1 == s2
- 地址 0x0011 != 0x0022
- 结果:false
情况3:String s = "ab" + "c";
编译器会直接优化为:String s = "abc";
内存同
情况1,== 比较为 true。
核心结论(背这个就够)
- == 永远只比较栈里存的地址
- 字符串字面量(双引号直接写)会进入常量池,同内容共用同一个地址
- new String(...) 一定会在堆上创建新对象,地址一定不同
- 想比较字符串内容是否一样,必须用 equals(),不能用 ==
延伸:equals 在 String 里的原理
String 类内部已经重写了 equals:
- 先判断是否同一对象(==)
- 再判断类型是否是 String
- 逐字符比较数组内容
所以只要内容一样,equals 就返回 true。

2819

被折叠的 条评论
为什么被折叠?



