StringBuffer/StringBuilder与使用加号“+”直接拼接字符串的区别

2023-10-27

一、使用“+”拼接字符串

1.字符串常量内存分析。

  首先我们要了解到,字符串常量是存储在常量池中的。在JDK1.7以前,常量池处于方法区当中。此时hotspot虚拟机对方法区的实现为永久代。对于永久代,大家需要了解他的一个特性,那就是GC不会对永久代内的数据进行垃圾回收

2.String类型特性。

  String类型很重要的一个特性就是,字符串是不可变的,他们的值在创建后无法更改。看下面两行代码:

        String s = "aaa";
        s = "abc";

  当执行第一行代码时,栈内存入栈了一个引用s,常量池存储了一个字符串常量“aaa”,s指向了“aaa”的地址。当执行第二行代码时,并不是"aaa"的内容改变成了“abc”,而是常量池中又存储了字符串常量“abc”,s指向的地址改为了“abc”的地址。“aaa”无引用指向,成为系统垃圾。

3.使用“+”拼接字符串时内存分析。

  根据上述永久代和String类型的特性,当我们使用“+”拼接字符串时就会发生浪费空间的问题。详情请看下面一段代码:

	String text1 = "abc";
	String text2 = "def";
	String text3 = "gh";
	text1 = text1+text2+text3;
	System.out.println(text1);

  此段代码看上去没有任何问题,运行后也输出了“abcdefgh”。那究竟为何会浪费空间呢?但让我们来分析一下此时内存中的变化。
  首先,前三条代码执行后,栈内存中已经入栈了text1,text2,text3三个变量,常量池中也存储了三个字符串常量,栈中的三个变量分别指向了所对应的地址。如下图:
创建String变量时的内存分析
  当执行第四行代码,字符串进行了拼接。此时注意,text1+text2+text3看起来是一个式子,但在执行过程中,内存中会新增加两个字符串常量。第一个是text1和text2拼接所生成的字符串(“abcdef”),第二个是第一个生成的字符串和text3字符串拼接后所生成的字符串(“abcdefgn”)。拼接完成后text1所指向的地址将会修改成最后生成的字符串地址,此时常量池中则出现了两个没有任何引用指向的常量,系统垃圾“abc”和“abcdef”。如下图:
字符串拼接后的内存
  而根据永久代的特性,这两个垃圾将不会被GC回收,成为“永久垃圾”!
此处看上去好像只是内存中多出了两个字符串而已,但如果业务规模大了起来,如果这种拼接是发生在一个大规模的循环体中,那么产生的垃圾可就不只是两个而已了,将会造成系统空间的大量浪费。

二、StringBuffer/StringBuilder拼接字符串分析

1.StringBuffer/StringBuilder对象创建时内存分析

  通常我们创建StringBuffer/StringBuilder对象方式如下:(以StringBuffer为例)

	StringBuffer s1 = new StringBuffer("abcd");

  当new关键字一出现,我们就应当知道,此时要创建一个对象了。而在Java中new出来的对象的实例存放在堆内存中,对象的引用存放在栈内存中。如下图:
创建StringBuffer对象的内存图

2.StringBuffer/StringBuilder拼接字符串分析

  与String类型不同的是,StringBuffer/StringBuilder是可变字符串,他们的值可以发生变化。请看以下代码:

        StringBuffer s1 = new StringBuffer("abcd");
        s1.append("efg");

  第一行代码执行后内存已经分析过,如上图。当执行第二行代码时,append()方法的作用就是在末尾拼接字符串,由于StringBuffer是可变字符串,所以拼接即发生在当前StringBuffer的实例上,无需再新建实例。即改变了原实例内的字符串内容,s1依然指向原地址。内存变化如下:
使用StringBuffer拼接字符串后内存变化
  以上例子均使用StringBuffer实现,StringBuilder进行拼接字符串操作时与StingBuffer相同。由此可见,使用StringBuffer/StringBuilder拼接字符串不会造成空间的浪费。

三、总结

  综上所述,当我们有需求要拼接字符串时,应尽量的去使用StringBuffer或StringBuilder。尽管“+”的使用非常便捷,但当业务需求变大时,造成的浪费可能会远远超出我们的想象。
  以上内容全是本人自己的理解,如哪里有错误,请大家及时指出,我会在确认后尽快修改。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

StringBuffer/StringBuilder与使用加号“+”直接拼接字符串的区别 的相关文章

  • 如果我在 XML 布局中声明一个片段,如何将它传递为 Bundle?

    我有一个活动已替换为片段 该活动采用了一个 Intent 其中包含一些有关该活动应该显示哪些数据的额外信息 现在 我的 Activity 只是执行相同工作的 Fragment 的包装器 如果我使用标记在 XML 中声明该片段 如何将该捆绑包
  • 如何用泛型返回类型推断方法的具体返回类型?

    给出以下接口 interface Random extends java util function Supplier
  • 如何设置评分栏的星星颜色?

    如何设置评分栏的星星颜色 我想要黄色星星 最简单的方法 android progressTint color color 光滑有光泽
  • 如何在 Jboss 7.1 中配置简单身份验证

    我正在从事由以下人员编写的项目纯jsps 脚本 不使用任何框架 jboss版本 jboss as 7 1 0 Final 我现在正在尝试在其上添加简单的身份验证 因此 当用户尝试浏览 jsp 时 比如说 http localhost myC
  • 我收到异常: java.lang.IllegalStateException: getOutputStream() 已被调用用于此响应

    我想编写代码来下载保留在我的系统中的文件 这是我的代码 在控制器类中 我有以下映射 RequestMapping value processFile method RequestMethod POST public ResponseBody
  • Checkstyle 规则防止调用某些方法和构造函数

    是否可以使用 Checkstyle 来禁止使用某些使用系统相关默认值 区域设置 字符集等 的构造函数或方法 我更喜欢强制执行一项政策 程序员应该明确了解系统相关的值 所以我认为以下物品是危险的 all the constructors of
  • 无法在IntelliJ IDEA中编译和运行java代码

    使用 IntelliJ IDEA 版本 12 1 6 我想运行 Horstmann Core Java 书中的示例 public class Welcome public static void main String args Strin
  • 如何将跨源资源共享与 Spring MVC 4.0.0 RESTful Webservice 集成

    我有一个简单的 Web 服务返回JSON data The 用户等级 com bargadss SpringService Domain 是个POJO类包含 用户 ID 名字 姓氏 电子邮件 The 用户服务类 com bargadss S
  • Selenium 2:中断页面加载

    我在使用 FirefoxDriver 使用 Selenium 2 0b3 Java API 单击按钮时遇到问题 单击该按钮会将表单发送到网络服务器 然后浏览器会因表单提交而进入新页面 当使用 element click 单击某个元素时 se
  • XmlAdapter 到 JAXB 绑定 Joda 的时间间隔?

    我已经被 Web 服务的 JAXB 绑定问题困扰了几个小时 为了准备一个必须返回 Joda Time 类实例 即时 持续时间 间隔等 的更大的 Web 服务 我从一个只有一个返回 Interval 的方法的 Web 服务开始 package
  • 导入数据期间解析日期格式的最佳方法

    我创建了在数据导入 400 K 记录 期间解析视图不同日期格式的方法 我的方法捕获 ParseException 并尝试在不同时使用下一种格式解析日期 问题 在数据导入期间设置正确的日期格式是更好的方法 更快 吗 private stati
  • 如果表不存在,如何使用 Derby Db 创建表

    我是新来的apache derby我似乎无法工作 CREATE TABLE IF NOT EXISTS table1 可以实现MySql等等我得到了 Syntax error Encountered NOT at line 1 column
  • 需要在 java api 中的 Solr 搜索中搜索文本及其周围的几行

    我正在使用 solr 7 7 2 并且我使用 solrj 在 Solr 中编写了一个 Java 程序 该程序在一个巨大的文本文件中搜索单词 我使用以下代码来显示代表整个文本的搜索结果 SolrQuery params new SolrQue
  • 策略模式的现实示例

    我一直在读关于OCP原理 http en wikipedia org wiki Open closed principle以及如何使用策略模式来实现这一目标 我打算尝试向几个人解释这一点 但我能想到的唯一例子是根据 订单 的状态使用不同的验
  • 蓝牙连接;无法正确发送字符串

    当我需要将字符串从服务器蓝牙套接字发送到客户端蓝牙套接字时 我的程序遇到了麻烦 只要我一次只发送一个字符串 例如聊天 一切都可以正常工作 但是如果我需要在短时间内编写更多字符串 以交换信息 则字符串将不会与客户端代码分离 例如 如果我发送
  • 遍历多行字符串

    我得到一些数据 def data some useless text n even more n finally interesting text 我怎样才能得到其中 有趣的部分 所以基本上所有行都不是以 开头的 Groovy 的一种选择是
  • Spring Boot MultipartFile上传getOriginalFileName根据浏览器不同而不同

    我使用的是 spring boot 1 5 7 RELEASE 版本 我使用以下方法上传文件 Autowired private MyService mySerice RequestMapping value uploadFile meth
  • Activity 在 Android 上创建两次

    首先 我是 Android 开发新手 所以请耐心等待 我将从用户界面开始 我有一个按钮 一旦您点击它 就会启动一个活动以获取结果 public class GUIActivity extends Activity Override publ
  • “您的安全设置已阻止本地应用程序运行”Java 8

    我正在尝试在 Chrome 窗口中运行一个小小程序 但收到错误消息 我确实看到所有回复都告诉我将安全性更改为中级 但版本 8 中不存在该选项 到目前为止 几个小时的谷歌搜索和向同学寻求帮助没有带来任何进展 有人可以建议一下吗 Medium在
  • 从 Web 服务器异步调用应用程序

    我有一个用 Spring 制作的 在 Tomcat 上运行的 Web 应用程序 在同一台机器上有一个普通的 Java 应用程序 我想通过从Web服务器调用Java应用程序来执行它 但我想让应用程序不会使用服务器的资源 它涉及分类器的训练 因

随机推荐

  • 线程池的简介说明

    在多线程应用程序开发中 如果我们不使用线程池 则每次创建和销毁线程将会消耗宝贵的CPU 内存资源 所以我们必须创建一个线程池 线程池的功能 线程池用于管理线程 用于减少系统资源消耗 创建一个线程池 实现思路 借助线程池类Executor 借
  • Java Map集合 体系

    1 Collection集合 1 1 常用集合的体系 mermaid svg dmg6k5CugOsij3Ax label font family trebuchet ms verdana arial font family var mer
  • openGL之API学习(九十四)几何着色器的几个参数设置含义

    设定输入几何图元的类型 比如GL TRIANGLES glProgramParameteriEXT program GL GEOMETRY INPUT TYPE EXT inputGeometryType 设定输出几何图元的类型 比如GL
  • Leetcode之KMP字符串算法

    针对题目28题 实现strStr 功能找出needle在haystack字符串的第一个位置 否则返回 1 当然有暴力法 但是时间复杂度是O mn 而KMP算法提前计算出needle字符串的重复数据加以利用 j能够有效的回退到可能的位置 时间
  • 树干树叶点云分类

    将扫描的树木点云的树干树枝和树叶分类出来 后续放出程序代码
  • Cluster & Docker

    操作系统解决主要问题之一就是如何在一台机器上调度硬件资源 比如为一个进程分配cpu gpu 存储资源等 使得进程可以高效 按照预期地完成运行 云和互联网解决的主要问题之一是如何在多台机器之间调度硬件资源or调度信息资源 这就产生了更丰富架构
  • SpringCloud最新版环境集成-2021年11月

    总述 之前搞过SpringCloud项目 但版本是netflix维护的伦敦地铁站名称的版本 现在想做一下笔记 并尝试最新版本 看有什么变动没 结果还真有一堆坑 此项目集成了eureka feign ribbon hystrix zuul五大
  • 在.Net 6项目中设置MySql数据库的连接配置文件appsettings.json及在Program.cs中读取配置文件并向DI容器注册服务。

    1 配置一 配置好ConnectionStrings 通过ConnectionString动态读取ServerVersion 推荐使用 appsettings json ConnectionStrings MoviesDBContext s
  • MFC + 自定义类的序列化与反序列化

    使类可序列化需要五个主要步骤 从 CObject 派生类 或从 CObject 派生的某个类中派生 重写 Serialize 成员函数 使用 DECLARE SERIAL 宏 在类声明中 定义不带参数的构造函数 为类在实现文件中使用 IMP
  • SQL 删除表数据行与重置自动增长字段

    delete 语句 delete from tablename 表名 where ID 列名 x 表示删除数据表中ID列的值为x的数据行 在ID列设置了自动增长主键列的情况下 这种删除方式将会保留该数据行所占用的自动增长值 此后添加数据时此
  • Linux内嵌链表(sys/queue.h)详解

    Linux 内嵌链表 sys queue h 详解 queue 简介 SLIST STAILQ LIST TAILQ CIRCLEQ 例程 queue 简介 C语言不像C 语言可以使用STL 在编程中需要用到链表时 通常需要程序员重新设计链
  • java中数据库重连

    当数据库重新启动 而导致程序无法连接 需要重启tomcat才能重连的解决办法 方法一 将连接池由DBCP改为C3P0 c3p0连接池本身具有数据库重连机制
  • 传统的目标检测算法

    1 基于滑动窗口的目标检测算法 滑动窗口 gt gt 特征提取 gt gt 分类器 图 滑动窗口目标检测流程 对输入的图像设置不同大小的滑窗 确定步长遍历整个图像 每次滑动完成后对当前选择框进行特征提取 SIFT HOG等 并使用事先训练好
  • python+opencv学习之路(一 )学习打开图片

    python opencv学习之路 一 学习打开图片 载入opencv和numpy模块 import cv2 import numpy as np 读取图片 img cv2 imread 1 jpg cv2 IMREAD COLOR 1 j
  • Android学习路线:如何成长为高级工程师

    博主参加了2014 CSDN博客之星评选 帮我投一票吧 点击给我投票 前言 之所以写这篇文章 是因为最近博客和我的开发群 215680213 中 不少小伙伴都让我讲讲android学习路线 所以我决定写一篇博客 来说明这个问题 既然有不少小
  • C++知识点37——拷贝构造函数

    无论是C 自定义的类还是STL内部的容器类 会显式的定义类的对象在拷贝 赋值和销毁时执行的操作 一个类通过五个成员函数来控制这些操作 拷贝构造函数 拷贝赋值运算符 移动构造函数 移动赋值运算符和析构函数 其中 拷贝构造函数和移动构造函数定义
  • 【SpingBoot】SpringBoot实现卷积神经模型代码

    下面是一个基本的卷积神经网络 CNN 模型代码示例 导入依赖
  • Ubuntu 经验 :设置EFI分区

    版权声明 本文为博主原创文章 遵循 CC 4 0 BY SA 版权协议 转载请附上原文出处链接和本声明 本文链接 https blog csdn net boyStray article details 88915155 ubuntu18默
  • VMware报错,无法连接到虚拟机,并且vmware-vmx.exe应用程序无法正常运行,报错0xc000007b

    试了很多修复 启动 禁用之类的方法发现不适用 最终发现是安装的其他软件导致C 库发生改变 解决 控制面板 程序 卸载程序 找到下图中的两个 右键 卸载 修复 之后VMware就能正常使用了
  • StringBuffer/StringBuilder与使用加号“+”直接拼接字符串的区别

    StringBuffer StringBuilder拼接字符串与使用加号 拼接字符串的区别 一 使用 拼接字符串 1 字符串常量内存分析 2 String类型特性 3 使用 拼接字符串时内存分析 二 StringBuffer StringB