Java 字符串拼接原理

原文:Java 字符串拼接原理

我们知道 Java 可以直接使用加号+来拼接字符串。

字符串+拼接的本质是使用StringBuilder.append()(已在Java8测试通过),最终如果要赋值给字符串变量时,会调用toString()

/*** 字符串追加*/
@Test
public void testStrAppend() {/** + 之前先隐式实例化 StringBuilder 对象* 每次 + 都是 append,期间不会 toString* 最后赋值给字符串时,会隐式调用 toString() 得到结果字符串*/String abc = "2";String def = "3";String str = "1" + abc + def;System.out.println(str);
}
字符串追加

特殊地,如果是字符串常量拼接,编译器会在编译期自动优化到一起,例如"1" + "2" + "3"会自动优化为"123"

使用+拼接字符串是 Java 语法糖。

/*** 字符串常量拼接*/
@Test
public void testConstantAppend() {// 如果是常量相加,那么编译器在编译为 class 文件时,会自动优化为一个常量String str = "1" + "2" + "3";
}
常量拼接会自动优化到一起

还需要注意的是在循环中如果使用+=其实会造成StringBuilder重复创建,导致资源浪费,因为每次+=都会 new 一次StringBuilder,并隐式toString()赋值给原字符串对象。

/*** 在循环中追加字符串* 在循环中 += 会造成资源浪费*/
@Test
public void testStrAppendInLoop() {/** 循环中不推荐使用 +=* 每次 += 相当于实例化一个新的 StringBuilder,然后调用 append(oldStr)、append(newStr)、toString()* 产生大量的 StringBuilder 对象*/String str = "";for (int i = 0; i < 100; i++) {str += i;}System.out.println(str);
}
循环中使用 += 每次都会创建 StringBuilder 导致资源浪费

总结:

对于字符串使用+拼接:

  1. 如果是常量相加,那么在编译器会自动合并为一个常量字符串(只要挨着的常量就会合并,前后声明不影响,例如"1" + "2" + def + "4" + "5"会自动合并为"12" + def + "45"

  2. 如果与变量相加,那么相加前会初始化StringBuilder对象,每次相加都append(str),如果赋值给String,最终会隐式调用toString()(即只在最后调用一次toString(),这是我们期望的)

需要注意的是,使用+=拼接,例如a += 123;等效于a = a + 123;,每次+=都会实例化一个新的StringBuilder对象,append(a).append(123)再隐式调用toString()(注意:每次+=因为要再次赋值给字符串a都会隐式toString())。

所以,如果在循环中使用+=,会产生大量StringBuilder对象(每次相加前都会实例化StringBuilder对象)和String对象(每次都会toString()),造成资源浪费。

最佳实践:

  1. 普通的字符串拼接,可以使用+拼接字符串(与手动创建StringBuilder对象,调用append()等效)

  2. 循环中字符串拼接,推荐手动创建StringBuilder对象调用append(),而不是+=(循环中+=会创建大量StringBuilderString对象)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/740042.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

scope-sentry-数据泄露规则提取

工具简述 Scope Sentry是一款具有资产测绘、子域名枚举、信息泄露检测、漏洞扫描、目录扫描、子域名接管、爬虫、页面监控功能的工具,通过构建多个节点,自由选择节点运行扫描任务。当出现新漏洞时可以快速排查关注资产是否存在相关组件。 对该工具分析主要是分析内部的信息泄…

es8.x 版本使用及 java api client

1.为什么不使用High Level REST Client 了 那在 ElasticSearch 7.15.0 版本开始,官方又不建议使用 High Level REST Client 了,为什么呢?因为它是基于原生的 REST API,而这些 API 在某些情况下限制了某些功能的性能优化。与此同时,官方也推出了 Elasticsearch Java 客户端…

7.7-DPday1

动态规划理论基础什么是动态规划 动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的 在关于贪心…

gitlab私有仓库搭建

安全:关闭防火墙,selinux 1.安装GItlab所需的依赖包 yum install curl policycoreutils-python openssh-server postfix wget -y安装gitlab 获取gitlab源码包 选择各种yum源去安装 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-12.0.3-ce.0.el7.x86_64…

[LeetCode] 134. Gas Station

想到了提前判断和小于0的情况,懒得写,果然被阴间用例10万个加油站坑了。 class Solution:def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:#1n = len(gas)if n ==1:if gas[0] >= cost[0]:return 0else:return -1#-1startpoint =[gas[x] - cost[…

算法金 | 推导式、生成器、向量化、map、filter、reduce、itertools,再见 for 循环

大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」不要轻易使用 For 循环 For 循环,老铁们在编程中经常用到的一个基本结构,特别是在处理列表、字典这类数据结构时。但是,这东西真的是个双刃剑。虽然看起来挺直白,一…

(三)变分自动编码器

过去虽然没有细看,但印象里一直觉得变分自编码器(Variational Auto-Encoder,VAE)是个好东西。于是趁着最近看概率图模型的三分钟热度,我决定也争取把VAE搞懂。于是乎照样翻了网上很多资料,无一例外发现都很含糊,主要的感觉是公式写了一大通,还是迷迷糊糊的,最后好不容…

大气热力学(8)——热力学图的应用之一

本篇文章源自我在 2021 年暑假自学大气物理相关知识时手写的笔记,现转化为电子版本以作存档。相较于手写笔记,电子版的部分内容有补充和修改。笔记内容大部分为公式的推导过程。 目录8.1 复习斜 T-lnP 图上的几种线8.1.1 等温线和等压线8.1.2 干绝热线8.1.3 湿绝热线8.1.4 等…

(二)变分贝叶斯

变分 对于普通的函数f(x),我们可以认为f是一个关于x的一个实数算子,其作用是将实数x映射到实数f(x)。那么类比这种模式,假设存在函数算子F,它是关于f(x)的函数算子,可以将f(x)映射成实数F(f(x)) 。对于f(x)我们是通过改变x来求出f(x)的极值,而在变分中这个x会被替换成一个…

03-码出高效:Java开发手册.pdf

03-码出高效:Java开发手册.pdf 03-码出高效:Java开发手册.pdf ​​ ​​ ‍ ​​ ‍ ‍

Franka Emika Datasheet(技术参数)

任何人均可随时随地实现自动化。 Franka Emika 是德国慕尼黑的一家深科技公司,该公司致力于创造全新的机器人平台技术,提高性能,改善每个人的访问便捷 性,从而克服现代社会面临的最大难题之一,让整整一代人摆脱枯燥乏味、存在潜在危险且极其耗时的劳动和工作。为了实现高 …

Ubuntu 22.04搭建MC原版服务端

首先下载 JAVA 版服务器 https://www.minecraft.net/zh-hans/download/server服务器下载java 21。这里我看了需求,如果你开mc服务器从1.20.5(24w14a)开始,运行Minecraft的最低要求是Java 21,且操作系统要求为64位。 apt install openjdk-21-jdk 运行就行。java -Xmx1G -Xm…