Java中字符串拼接时究竟创建了多少个String对象?

来源:AI社区作者:关中王头衔:草根站长
导读:本期聚焦于小伙伴创作的《Java中字符串拼接时究竟创建了多少个String对象?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Java中字符串拼接时究竟创建了多少个String对象?》有用,将其分享出去将是对创作者最好的鼓励。

Java中的字符串拼接是非常常见的操作,不同的拼接方式背后涉及的对象创建逻辑差异很大,核心和字符串常量池、拼接的实现机制有关。下面我们通过具体的代码示例来逐一分析不同场景下的对象创建情况。

Java中字符串拼接时究竟创建了多少个String对象?

字面量直接拼接的场景

当拼接的双方都是字符串字面量时,编译器会在编译期就完成拼接优化,不会在运行时创建新的对象。我们看下面的代码:

public class StringConcatTest {
    public static void main(String[] args) {
        // 字面量直接拼接
        String s1 = "hello" + "world";
        String s2 = "helloworld";
        // 输出true,说明s1和s2指向同一个常量池对象
        System.out.println(s1 == s2);
    }
}

这段代码中,<code>"hello" + "world"</code>在编译期就会被优化为<code>"helloworld"</code>,所以s1和s2都会指向字符串常量池中已有的<code>"helloworld"</code>对象,整个过程没有创建新的String对象,对象创建数量为0。

包含变量的字符串拼接场景

如果拼接的双方包含变量,编译器无法在编译期确定最终的结果,会在运行时通过<code>StringBuilder</code>来实现拼接,这时候就会涉及多个对象的创建。我们看下面的示例:

public class StringConcatTest2 {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = s1 + "world";
        String s3 = "helloworld";
        // 输出false,说明s2指向的是堆中的新对象
        System.out.println(s2 == s3);
    }
}

这段代码的执行过程如下:

  • 首先在字符串常量池创建<code>"hello"</code>对象,s1指向它
  • 执行<code>s1 + "world"</code>时,会先创建一个<code>StringBuilder</code>对象
  • 然后调用<code>StringBuilder</code>的<code>append</code>方法拼接内容,之后调用<code>toString</code>方法,<code>toString</code>方法会创建一个新的String对象,这个对象存放在堆中,内容是<code>"helloworld"</code>
  • 字符串常量池中原本就有<code>"helloworld"</code>对象,s3指向它

所以这个场景下,总共创建了2个新对象:1个<code>StringBuilder</code>对象和1个堆中的String对象。

使用StringBuilder主动拼接的场景

如果我们主动使用<code>StringBuilder</code>来拼接字符串,对象创建的数量会更可控,我们看下面的代码:

public class StringConcatTest3 {
    public static void main(String[] args) {
        String s1 = "hello";
        StringBuilder sb = new StringBuilder();
        sb.append(s1);
        sb.append("world");
        String s2 = sb.toString();
        String s3 = "helloworld";
        // 输出false,s2指向堆中的新String对象
        System.out.println(s2 == s3);
    }
}

这个场景的对象创建情况:

  • 字符串常量池创建<code>"hello"</code>对象,s1指向它
  • 创建1个<code>StringBuilder</code>对象
  • 执行<code>sb.toString()</code>时,创建1个堆中的String对象,内容是<code>"helloworld"</code>

这里同样创建了2个新对象,和包含变量的拼接场景对象数量一致,但主动使用<code>StringBuilder</code>可以避免多次拼接时重复创建<code>StringBuilder</code>对象,性能更好。

拼接后调用intern方法的场景

如果拼接得到的String对象调用了<code>intern</code>方法,情况又会发生变化,我们看下面的示例:

public class StringConcatTest4 {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = s1 + "world";
        // 调用intern方法,尝试将字符串放入常量池
        String s3 = s2.intern();
        String s4 = "helloworld";
        // 输出true,说明s3和s4指向同一个常量池对象
        System.out.println(s3 == s4);
    }
}

这里<code>s2</code>是堆中的String对象,调用<code>intern</code>方法时,如果常量池中已经有<code>"helloworld"</code>,就会直接返回常量池中的对象引用,不会创建新对象。如果常量池中没有,就会把<code>s2</code>的引用放入常量池,同样不会创建新的String对象。所以这个场景下对象创建数量和之前包含变量的拼接场景一致,还是2个新对象。

不同场景对象数量总结

我们可以通过下面的表格来汇总不同拼接场景的对象创建数量:

拼接场景新创建对象数量说明
字面量直接拼接0编译期优化,直接使用常量池已有对象
包含变量的拼接21个StringBuilder对象,1个堆中String对象
主动使用StringBuilder拼接21个StringBuilder对象,1个堆中String对象
拼接后调用intern方法2intern不会新增String对象,仅调整引用

在实际开发中,如果是少量的字符串拼接,使用<code>+</code>操作符即可,编译器会做一定的优化;如果是循环或者大量的字符串拼接,建议主动使用<code>StringBuilder</code>,避免重复创建<code>StringBuilder</code>对象带来的性能损耗。同时理解对象创建的数量,也能帮助我们更好地应对相关的面试问题,搞清楚字符串拼接背后的实现逻辑。

JavaString字符串拼接对象创建修改时间:2026-07-21 21:51:36

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。