java String字符串拼接原理分析及说明

 更新时间:2026年06月13日 09:54:26   作者:路窑  
这段文章详细解释了Java中字符串拼接的三种情况及其底层原理,包括常量与常量拼接、常量与变量拼接以及变量与变量拼接,特别强调了StringBuilder类在变量参与拼接中的应用

字符串的拼接可以分为下面三种情况

1. 字符串常量与字符串常量的拼接

String s1 = "a"+"b"+"c";

2. 字符串常量与变量的拼接

String s1 = "a";
String s2 = s1+"b";

3. 变量与变量的拼接

String s1 = "a";
String s2 = "b";
String s4 = s1+s2;

(1)常量与常量的拼接原理

字符串常量之间的拼接操作在未加载到内存之前就已经完成了。

在前端编译期间(即将.java源文件编译为.class字节码文件),会对字符串常量之间的拼接操作进行优化。

对应的指令:

可以看到对于s1和s2这两个局部变量,它们指向的是常量池中同一个对象,它们存储的都是常量池中"abc"对象的地址。所以在指向==运算时其结果为true。

(2)变量参与的字符串拼接操作底层原理

字符串拼接操作中只要其中有一个是变量,结果就在堆中。且变量拼接的原理是创建一个StringBuilder类的对象,调用其append方法,拼接完成后再调用该对象的toString()方法(该方法已经被重写了)返回一个字符串对象

 public void test1(){
        String s1 = "a";
        String s2 = "b";
        String s3 = "ab";
        String s4 = s1+s2;
        System.out.println(s3==s4);//结果为false
    }

对应的字节码:

 0 ldc #5 <a>
 2 astore_1
 3 ldc #6 <b>
 5 astore_2
 6 ldc #7 <ab>
 8 astore_3
 9 new #8 <java/lang/StringBuilder>
12 dup
13 invokespecial #9 <java/lang/StringBuilder.<init>>
16 aload_1
17 invokevirtual #10 <java/lang/StringBuilder.append>
20 aload_2
21 invokevirtual #10 <java/lang/StringBuilder.append>
24 invokevirtual #11 <java/lang/StringBuilder.toString>
27 astore 4
29 getstatic #3 <java/lang/System.out>
32 aload_3
33 aload 4
35 if_acmpne 42 (+7)
38 iconst_1
39 goto 43 (+4)
42 iconst_0
43 invokevirtual #4 <java/io/PrintStream.println>
46 return
  1. 加载字符串常量池中的a,将a的地址存储在局部变量表1的位置,即变量s1中
  2. 加载字符串常量池中的b,将b的地址存储在局部变量表2的位置,即变是s2
  3. 加载字符串常量池中的ab,将ab的地址存储在局部变量表2的位置,即变量s3中
  4. 在对以局部变量s1和s2进行字符串拼接的时候,首先创建了一个StringBuilder对象,调用其构造器方法init().
  5. 将局部变量表中的下标为1、2的变量加载到操作数栈中,然后调用append方法添加到StringBuider对象的末尾,即实现了a、b字符串的连接
  6. 最后调用StringBuilder的toString方法生成—个新的String对象返回

特别注意:

StringBuilder的toString()方法调用的时String重载的构造器方法,是以字符数组为字符串实际内容进行创建的,并未直接以字面量方式进行创建String对象,即:

由于未直接出现字面量("abc"这种,下面s1、s2、s3等号右边都直接出现了字面量,会在字符串常量池创建对应的对象),不会在字符串常量池中创建对应的对象。

StringBuilder调用toString()方法创建的String对象会直接在堆中为其分配内存,常量池中不存在对应的对象

 public void test1(){
        String s1 = "a";
        String s2 = "b";
        String s3 = "ab";
        String s4 = s1+s2;
        System.out.println(s3==s4);//结果为false
    }

所以s3引用指向的时字符串常量池中的"ab"对象,而s4指向的时堆中的"ab"对象,二者指向的地址不同,所以进行==操作的结果为false。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java包含抽象方法的枚举类示例

    Java包含抽象方法的枚举类示例

    这篇文章主要介绍了Java包含抽象方法的枚举类,结合实例形式分析了Java包含抽象方法的枚举类实现方法与相关操作技巧,需要的朋友可以参考下
    2019-08-08
  • Java 模拟cookie登陆简单操作示例

    Java 模拟cookie登陆简单操作示例

    这篇文章主要介绍了Java 模拟cookie登陆简单操作,结合实例形式分析了Java 模拟cookie登陆的相关原理与基本实现技巧,需要的朋友可以参考下
    2020-03-03
  • Guava自动加载缓存LoadingCache使用实战详解

    Guava自动加载缓存LoadingCache使用实战详解

    这篇文章主要为大家介绍了Guava自动加载缓存LoadingCache使用实战详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • SpringMVC如何获取多种类型数据响应

    SpringMVC如何获取多种类型数据响应

    这篇文章主要介绍了SpringMVC如何获取多种类型数据响应,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-11-11
  • 一文彻底吃透Java程序逻辑控制

    一文彻底吃透Java程序逻辑控制

    Java程序的执行并非永远是从上到下逐行执行,程序逻辑控制就是通过特定语法结构改变代码的执行顺序、选择执行指定代码、重复执行某段代码的核心语法,这篇文章主要介绍了Java程序逻辑控制的相关资料,需要的朋友可以参考下
    2026-05-05
  • AsyncHttpClient ListenableFuture源码流程解读

    AsyncHttpClient ListenableFuture源码流程解读

    这篇文章主要为大家介绍了AsyncHttpClient ListenableFuture源码流程解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • Java 访问剪切板(复制,粘贴)的示例

    Java 访问剪切板(复制,粘贴)的示例

    这篇文章主要介绍了Java 访问剪切板(复制,粘贴)的示例,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下
    2020-11-11
  • Java Agents代理是什么

    Java Agents代理是什么

    Java代理Agents通过提供使我们能够侵入JVM中正在运行的Java程序的服务,在最底层工作。Java的这一强大但不可思议的部分具有在错误操作时使JVM崩溃的能力。本文简要介绍了这个概念,并介绍了它的工作原理。需要的朋友可以参考下面文章的具体内容
    2021-09-09
  • Springboot 2.6集成redis maven报错的坑记录

    Springboot 2.6集成redis maven报错的坑记录

    这篇文章主要介绍了Springboot 2.6集成redis maven报错的坑记录,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • Linux centos7环境下jdk安装教程

    Linux centos7环境下jdk安装教程

    这篇文章主要为大家详细介绍了Linux centos7环境下jdk的安装教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03

最新评论