热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

javaString字符串拼接原理

java中的字符串的拼接可以分为下面三种情况:1.字符串常量与字符串常量的拼接Strings1abc;2.字符串常量与变量的拼接Strings1a

java中的字符串的拼接可以分为下面三种情况:
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_13 ldc #6 <b>5 astore_26 ldc #7 <ab>8 astore_39 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。


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 【GO】k8s 管理系统项目的前端部分16–前端布局详解
    【GO】k8s管理系统项目[前端部分–前端布局]1.前端布局2.Layout2.1layoutsrclayoutLayout.vue ... [详细]
author-avatar
虎爷在江湖
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有