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

Java 9循环字符串拼接:对象创建数、中间对象及验证方法咨询

关于循环中字符串拼接的对象创建问题拆解

嘿,这个问题问到点子上了,咱们结合Java版本差异一步步说清楚:

1. 循环中创建的对象数量(分Java版本)

首先得明确:循环外的初始空字符串""和List里的"a"/"b"/"c"属于常量池复用对象,不算循环内创建的。咱们只算循环过程中生成的对象:

Java 8 场景

每次result += n,编译器会把它翻译成等价的代码:

result = new StringBuilder(result).append(n).toString();

所以3次循环下来:

  • 每次循环创建1个StringBuilder对象,共3个
  • 每次toString()会生成1个新的String对象(因为String不可变,toString会基于拼接后的char数组新建String),共3个
  • 总计:6个对象

Java 9+ 场景

Java 9引入了StringConcatFactory和invokedynamic优化字符串拼接,虽然底层实现更高效(比如直接用数组拼接、避免频繁扩容),但循环中的+=依然无法被编译器优化为单次拼接容器复用。每次循环还是会生成1个新的String对象,同时可能伴随少量临时数组/辅助对象(但核心可计数的对象还是3个新String)。

2. 是否存在中间对象?

肯定存在!

  • Java 8中:每次循环生成的StringBuilder和非最终的String对象(前两次循环的"a"、"ab")都是中间对象——它们仅作为拼接过渡,循环结束后就会变成垃圾被回收,只有最后一个"abc"被保留在result中。
  • Java 9+中:虽然没有显式的StringBuilder,但每次循环生成的临时String对象(同样是前两次的"a"、"ab")依然是中间对象,本质和Java 8一样,只是底层拼接方式更高效而已。

3. 如何验证这一点?

这里分享几个实用的验证方法:

方法1:查看编译后的字节码

用javac编译你的代码,然后执行javap -c 你的类名查看字节码指令:

  • Java 8中,你会看到每次循环里都有new StringBuilder、invokespecial StringBuilder.<init>、append、toString的指令,证明每次都在新建StringBuilder和String。
  • Java 9+中,会看到invokedynamic指令调用java.lang.invoke.StringConcatFactory.makeConcatWithConstants,但依然是每次循环执行一次这个调用,生成新的String。

方法2:监控内存与对象创建

把循环次数改成10000次(放大效果),然后用JVM参数追踪:

  • 加上-XX:+PrintGC运行程序,会看到频繁的小GC——这就是大量中间对象被回收导致的。
  • 对比用单个StringBuilder的写法(StringBuilder sb = new StringBuilder(); for(...) sb.append(n); String result = sb.toString();),你会发现GC次数大幅减少,因为没有了大量中间对象。

方法3:调试观察对象地址

在循环中打印System.identityHashCode(result),你会发现每次循环后result的哈希值都不一样——这说明每次都是新的String对象,证明中间对象存在。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:01:17