StringBuilder.append()为何会影响String.intern()的对象比较结果
Java String#intern() 对比结果差异原因解析
前置前提
以下结论基于JDK7及更高版本的实现,JDK6因字符串常量池位于永久代、intern()逻辑不同,和本文描述结果存在差异。
String.intern()核心规则
JDK7将字符串常量池从永久代迁移到堆空间后,intern()的执行逻辑为:
- 调用方法时首先查询字符串常量池中是否存在当前字符串内容对应的引用
- 若存在,直接返回常量池存储的引用
- 若不存在,会将当前堆中该String对象的引用直接存入常量池,再返回该引用
两个测试用例的差异分析
s3对比返回false的原因
s3的构造代码为:
String s3 = new StringBuilder("aaaa").toString();
代码中传入StringBuilder构造方法的"aaaa"是字符串字面量,JVM在类加载的解析阶段就会将该字面量对应的String对象引用存入字符串常量池。后续toString()生成的s3是堆中新创建的独立String对象,和常量池中的"aaaa"对象地址不同。
调用s3.intern()时,常量池已经存在"aaaa"的引用,因此返回的是常量池中的旧引用,和堆中的s3对象地址不一致,==对比结果为false。
s1对比返回true的原因
s1的构造代码为:
String s1 = new StringBuilder("dsada").append("dfgdfgd").toString();
s1最终的字符串内容为dsadadfgdfgd,这个拼接后的完整字符串没有作为字面量在类加载阶段存入常量池。第一次调用s1.intern()时,常量池中不存在该内容的引用,因此会直接将s1本身的堆引用存入常量池,返回值就是s1的引用,因此==对比结果为true。
内容的提问来源于stack exchange,提问作者concurrentScott
相关产品推荐
相关产品推荐

