You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中concat()返回的堆字符串调用intern()为何与原引用相等

Java String#intern() 输出true的底层逻辑说明

你运行的代码如下:

String s1 = new String("Hello");  
String s2 = s1.concat("World"); 

String s3 = s2.intern(); 
System.out.println(s2 == s3); // returns true

你原本的认知对应Java 6及更早版本的intern实现规则,Java 7之后字符串常量池(SCP)的存储位置和intern逻辑做了调整,是该输出结果的核心原因:

  • Java 6及更早版本中SCP位于永久代,调用intern时如果常量池没有对应字符串,会复制当前堆对象的内容到永久代生成新对象,返回新对象的引用,此时s2 == s3会输出false
  • Java 7及之后版本SCP移到堆空间,intern逻辑优化为:如果常量池中没有和当前字符串内容相等的引用,会直接把当前堆中字符串对象的引用存入常量池,不会额外创建新对象,返回值就是原堆对象的引用
  • 你的代码执行时,s2是堆中生成的HelloWorld对象,调用s2.intern()前常量池没有对应HelloWorld的引用,因此intern方法直接将s2的引用存入常量池,返回的s3和s2指向完全相同的对象,==比较结果为true

可以通过以下对比代码验证该逻辑:

// 提前通过字面量在常量池创建HelloWorld对象
String pre = "HelloWorld";

String s1 = new String("Hello");  
String s2 = s1.concat("World"); 
String s3 = s2.intern();

// 此时intern返回常量池已有的pre对象引用,和堆中的s2不是同一个对象
System.out.println(s2 == s3); // 输出false

内容的提问来源于stack exchange,提问作者Ayush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 05:54:06