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

StringBuilder/StringBuffer的toString()是否生成新不可变String及规避方法

关于StringBuilder/StringBuffer的toString()方法的疑问解答

嘿,这个问题问到点子上了,这也是很多Java开发者刚接触可变字符串时容易搞混的细节,我来逐一给你解释清楚:

1. StringBuilder或StringBuffer的toString()是否会创建新的不可变String?

答案是肯定的。我们可以直接看JDK源码里的实现:

  • StringBuilder的toString()方法会调用new String(value, 0, count),基于自身内部的字符数组创建一个全新的String实例。
  • StringBuffer的实现逻辑类似,只不过它的方法是线程安全的(加了synchronized修饰),但最终同样会生成新的String对象。

这个新创建的String和普通String一样,是完全不可变的——因为String类的字符存储数组(JDK9+为byte数组)被final修饰,且没有对外暴露修改内部数组的方法,一旦生成就无法被改变。

2. 调用toString()会在字符串常量池中生成新的String吗?如何避免?

首先明确:默认情况下不会。

String常量池(JDK7及以后存放在堆中)里的字符串,一般来自这几种场景:

  • 直接编写的字符串字面量(比如"hello")
  • 主动调用String的intern()方法的字符串对象
  • 编译期可确定的字符串拼接结果(比如"a"+"b"会被编译成"ab"直接入池)

而StringBuilder.toString()生成的String对象,默认存放在堆的普通区域,不会自动进入常量池。只有当你主动调用这个String对象的intern()方法时,才会把它的引用放入常量池(前提是常量池里没有相同内容的字符串)。

所以如果要避免在常量池生成对应的String,只要不调用该String对象的intern()方法就可以了。日常开发中如果没有特殊需求(比如字符串复用、减少内存占用),其实根本不需要调用intern(),自然也就不会在常量池生成额外实例。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:56:34