商城首页欢迎来到中国正版软件门户

您的位置:首页 >String.intern()方法详解:手动入池技巧

String.intern()方法详解:手动入池技巧

  发布于2026-02-14 阅读(0)

扫一扫,手机访问

String.intern() 返回常量池中已存在字符串的引用,内容相同即复用;若不存在则将当前字符串内容放入池并返回其引用,与是否为字面量无关。

详解Java中的String.intern()方法_手动将字符串放入常量池

String.intern() 什么时候会返回堆上对象的引用

它不总返回常量池里的“新”对象,而是返回池中已存在字符串的引用;如果不存在,才把当前字符串(注意:是当前 String 对象的字符内容)放入池,并返回该引用。关键在于“内容相同即复用”,和你调用的是不是字面量无关。

常见错误现象:"abc".intern() == "abc"true,但 new String("abc").intern() == new String("abc")false —— 因为右边是堆上新对象,左边是常量池引用,两者地址不同。

  • 使用场景:避免重复字符串占用内存(如解析大量 JSON 字段名、日志中的固定标签)
  • 参数差异:无参数,纯实例方法,对 null 调用会抛 NullPointerException
  • 性能影响:首次调用需查表+可能插入,有锁开销(JDK 7+ 改到堆上,但仍是同步操作)

JDK 6 和 JDK 7+ 的 intern() 行为差异

JDK 6 把字符串常量池放在永久代(PermGen),空间小且不可扩容;JDK 7 起移到 Java 堆,受 GC 管理,行为更可控。这意味着在 JDK 6 中滥用 intern() 容易触发 java.lang.OutOfMemoryError: PermGen space,而 JDK 7+ 更多是堆内存压力。

典型误判:以为 intern() 总能“省内存”,其实它只是把字符串从堆某处挪到常量池——如果原对象还被强引用着,反而多占一份。

  • 必须确认字符串生命周期:长期存活、高复用率的才适合 intern()
  • JDK 8u20+ 默认开启 -XX:+UseG1GC 后,常量池回收更积极,但依然不会回收仍被引用的 interned 字符串
  • 验证方式:用 jmap -histo:live <pid> 查看 java.lang.String 实例数,配合 jstat -gc <pid> 观察老年代变化

为什么 String.valueOf(x).intern() 不等于 x.toString().intern()

因为 String.valueOf(null) 返回的是字符串 "null",而 null.toString() 直接抛 NullPointerException。哪怕 x 是非 null 对象,valueOf 可能调用 toString(),但也可能走分支逻辑(比如 String.valueOf(char[]) 直接构造新字符串)。

容易踩的坑:用 intern() 做 key 归一化时,没统一入口,导致相同语义的字符串进了两次常量池。

  • 永远优先用 String.valueOf(x) 替代 x.toString() 做空安全转换
  • 若 x 是 Integer 等包装类,String.valueOf(42)42 + "" 都会生成新对象,再 intern() 才进池
  • 数字转字符串后 intern() 效果有限:除非大量重复数值(如状态码 "200""404"),否则性价比低

用 intern() 做字符串比较前,先问自己三个问题

它不是万能的“加速器”。很多场景下,用 equals()==(仅限确定是字面量或已 intern 过)更直接可靠。

  • 这个字符串是否真的会在整个应用生命周期里高频出现?(比如配置项 key、协议字段名)
  • 有没有其他线程同时调用 intern()?高并发下锁竞争会让它变慢
  • 你能否控制所有创建路径?一旦漏掉某个构造方式(比如用了 StringBuilder.toString() 却没 intern()),比较就会失效

最常被忽略的一点:常量池里的字符串,只要被任何地方强引用着,就不会被 GC;而堆上字符串可以随时回收。所以“省内存”是有代价的——换来的可能是更难排查的内存泄漏。

本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。
  • UC浏览器隐藏功能在哪里?uc浏览器隐藏用法教程 正版软件
    UC浏览器隐藏功能在哪里?uc浏览器隐藏用法教程
    还在纠结UC浏览器隐藏功能有哪些?莫慌,小编为你送上最详尽的UC浏览器隐藏用法教程,带你轻松玩转UC浏览器!uc浏览器隐藏用法教程1、打开UC智能组件!有超多方便大家快乐冲浪滴组件可以添加和开启!2、模式组件里有很多实用功能最推荐阅读模式啦!
    16小时前 13:22 0
  • 王者营地怎么qq和微信一起玩?王者荣耀王者营地跨区组队操作教程 正版软件
    王者营地怎么qq和微信一起玩?王者荣耀王者营地跨区组队操作教程
    王者营地怎么qq和微信一起玩?众所周知,《王者荣耀》作为腾讯旗下的一款大型竞技类游戏网,支持微信和QQ登录,但是两者并不互通,在游戏登陆界面就可以看见,QQ登陆和微信登陆是完全两个不同的入口。因此很多玩家为了跟不同的好友一起玩,不得不开两个号。
    16小时前 13:10 0
  • 支付宝怎么加好友?支付宝加好友的流程教程 正版软件
    支付宝怎么加好友?支付宝加好友的流程教程
    支付宝怎么加好友?支付宝相信大家都用吧,支付宝的好友转账大家应该也会平时用到,那如果没有好友要怎么进行转账呢,那当然是先加好友了,接下来小编将给大家带来支付宝添加好友的方法教程,一起往下看看吧!支付宝加好友的流程教程1、首先进入支付宝首页后,点击下方导航栏中的消息选项2、在消息页面中,点击右上角的加号标志3、在加号标志选项中找到添加好友并点击4、进入添加好友页面
    17小时前 12:27 0
  • 支付宝怎么转账到别人银行卡?支付宝转账到别人银行卡方法教程 正版软件
    支付宝怎么转账到别人银行卡?支付宝转账到别人银行卡方法教程
    支付宝怎么转账到别人银行卡?支付宝是我们最常用的支付工具,用户在使用的时候经常会用到转账功能,相信很多小伙伴把钱转到自己银行卡的方法都会,那么怎么转账到别人的银行卡呢?还不清除的小伙伴快跟随小编一起来看看吧。
    17小时前 12:17 0
  • 支付宝如何关闭免密支付?支付宝关闭免密支付方法教程 正版软件
    支付宝如何关闭免密支付?支付宝关闭免密支付方法教程
    支付宝如何关闭免密支付?虽然支付宝免密支付让我们的生活变得更加便捷,但是在某些时候也会带来不必要的麻烦,如果你不小心将手机遗失或者被盗,那么可能会导致支付宝被人恶意盗刷,所以有时候关闭支付宝免密支付也显得尤为重要,下面小编就给大家带来了支付宝关闭免密支付的方法教程,希望能帮到大家。
    17小时前 12:06 0

热门关注