不能用 + 拼接字符串? 这次我要吊打面试官!
好久没维护《吊打面试官》系列了,今天再来一篇,这次真的要吊打了,哈哈!(看往期吊打系列请在后台回复:吊打,我会陆续更新……)
我们做 Java 程序员以来,不管是工作当中,还是面试过程中,都知道:字符串拼接不能用 String,要用 StringBuilder
或者是 StringBuffer
,以至于它们都被滥用了。
StringBuilder、StringBuffer 简称:SB,下文统一用 SB
代替。
SB
它们都是可变的字符串,它们之间的区别也是 Java 初中级面试战场上出现几率十分高的一道题,上场率没有 90% 也有 80% 吧。
这两个的具体区别请看这篇文章:StringBuffer 和 StringBuilder 的 3 个区别。
我们反过来想下,String真的是不可变的么?不一定,看下这篇:Java 中的 String 真的是不可变的吗?
当然,本文不是讨论字符串可变与不可变的问题,而是讨论:字符串拼接一定要用 SB
吗?为什么不能用 +
?能不能用 +
?什么时候可以用 +
?
为什么不能用 + 号拼接字符串?我不服,接下来我要吊打面试官!
什么时候不能用 `+`
通过多个表达式完成一个字符串拼接操作。
private void test1() {String www = "www.";String str = www;str += "javastack.";str += "com";
}
字节码如下:
// access flags 0xA
private static test2()V
L0
LINENUMBER 14 L0
LDC "www."
ASTORE 0
L1
LINENUMBER 15 L1
ALOAD 0
ASTORE 1
L2
LINENUMBER 16 L2
NEW java/lang/StringBuilder
DUP
INVOKESPECIAL java/lang/StringBuilder.<init> ()V
ALOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
LDC "javastack."
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
ASTORE 1
L3
LINENUMBER 17 L3
NEW java/lang/StringBuilder
DUP
INVOKESPECIAL java/lang/StringBuilder.<init> ()V
ALOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
LDC "com"
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
ASTORE 1
L4
LINENUMBER 18 L4
RETURN
L5
LOCALVARIABLE www Ljava/lang/String; L1 L5 0
LOCALVARIABLE str Ljava/lang/String; L2 L5 1
MAXSTACK = 2
MAXLOCALS = 2
不会查看字节码的,看这里:3种骚操作,教你查看 Java 字节码,看这一篇就会了。
观察下,NEW java/lang/StringBuilder
出现了两次,是因为我们在代码中拼接了两次,也就是说每一次拼接操作都会创建一次 StringBuilder
。
如果我们是在一个循环中进行字符串拼接,那是不是一次拼接就要创建一个 StringBuilder
?
wtf……这哪能接受!频繁创建对象是有性能开销的,这也是为什么我们常说的字符串不能用 +
拼接,而要用那两个 SB
拼接了。
什么时候可以用 `+`
直接将三个字面量的字符串拼接成一个字符串。
private static void test2() {String str = "www." + "javastack." + "com";
}
字节码如下:
// access flags 0x2
private test2()V
L0
LINENUMBER 13 L0
LDC "www.javastack.com"
ASTORE 1
L1
LINENUMBER 14 L1
RETURN
L2
LOCALVARIABLE this Lcom/test/jdk/TestSB; L0 L2 0
LOCALVARIABLE str Ljava/lang/String; L1 L2 1
MAXSTACK = 1
MAXLOCALS = 2
从字节码看出,没有任何创建 StringBuilder
的指令,直接从常量池进行取出一个完整的字符串:www.javastack.com。很明显,这是 Java 编译器对代码进行了优化。
所以,通过这个示例告诉你,在这种情况下是可以用 +
号进行字符串拼接的。
这个示例可以演变成我们实际工作当中的某个 SQL 语句拼接的案例,如:
String sql = "select name, sex, age, address"+ "from t_user"+ "where age > 18";
别说这样不行,这样是行的。
但你要是换成这样就不行了:
String sql = "select name, sex, age, address";
sql += "from t_user";
sql += "where age > 18";
这样又回到创建多个 StringBuilder
的时候了。
也就是说,在一个表达式中完成字符串拼接是可以用 +
号完成的,因为编译器已经做了优化。
小结一下
你只需要记住这两点:
1、在循环和多个表达式中不能 +
,频繁创建 SB
性能影响;
2、在单个表达式中可以用 +
,编译器直接做了优化;
老铁们,都搞清楚了?
这个观点有没有被误解很久?
下次面试,把这篇内容亮出来,吊打面试官,没问题的。
有收获的朋友一定要点个在看,这样我写原创更带劲了,谢了,老铁们。
不能用 + 拼接字符串? 这次我要吊打面试官!相关推荐
- java字符串转数组,吊打面试官
蚂蚁金服一面: 先自我介绍,讲讲自己基础掌握情况,以及项目经历平时会用到哪些数据结构? 链表和数组的优缺点? 解决hash冲突的方法有哪些? 讲讲自己对HashMap的理解,以及和Weakhashma ...
- Spring事务失效的 8 大原因,这次可以吊打面试官了!
今天再来一篇<吊打面试官>系列,这次真的要吊打了,哈哈!(看往期吊打系列请在后台回复:吊打,我会陆续更新--) 前几天栈长不是发了一篇文章,里面有一个关于事务失效的问题: 用 Spring ...
- 吊打面试官!Redis 常见面试题请收好 | 原力计划
作者 | 敖丶丙 责编 | Elle 出品 | CSDN 博客 你知道的越多,你不知道的越多 GitHub地址 https://github.com/AobingJava/JavaFamily 已经开 ...
- mysql 触发器条件判断偶尔失效_mysql┃多个角度说明sql优化,让你吊打面试官!...
正文约: 4744字 预计阅读时间: 12分钟 文章首发于我的微信公众号:moon聊技术,欢迎大家关注 mysql┃多个角度说明sql优化,让你吊打面试官! 目录 目录 前言 正文 1.表结构优化● ...
- 《吊打面试官》系列-Redis基础
你知道的越多,你不知道的越多 前言 Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对小伙伴们进行360°的刁难.作为一个在互联网公司面一次拿一次o ...
- 【转】MySQL 三万字精华总结 + 面试100 问,吊打面试官绰绰有余(收藏系列)
MySQL 三万字精华总结 + 面试100 问,吊打面试官绰绰有余(收藏系列) 本文公众号来源:JavaKeeper作者:派大新 写在之前:不建议那种上来就是各种面试题罗列,然后背书式的去记忆,对技术 ...
- 《吊打面试官》系列-Redis常见面试题
前言 Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对小伙伴们进行360°的刁难. 作为一个在互联网公司面一次拿一次Offer的面霸,打败了无数竞 ...
- ❤️手撕这十道HiveSQL题还不能吊打面试官,却能保你不被吊打❤️【推荐收藏】
全网最详细的大数据Hive文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 前言 HiveSQL十题 第一题 1.需求 2.数据准备 3. ...
- 重复订单号校验_吊打面试官系列重复消费、顺序消费、分布式事务
你知道的越多,你不知道的越多 前言 消息队列在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在消息队列的使用和原理方面对小伙伴们进行360°的刁难. 作为一个在互联网公司面一次拿一次Of ...
最新文章
- 如何利用 AI 对抗疫情?
- 《父亲家书》选:父亲的忙碌和欣喜
- Entityframework:“System.Data.Entity.Internal.AppConfig”的类型初始值设定项引发异常。
- mysql limit优化_MySQL:教你学会如何做性能分析与查询优化
- 在win8上配置网站服务器,win8怎么配置web服务器地址
- 区块链BaaS云服务(13)广州微链GGC全球游戏链(Global Game Chain)
- kali - Nmap
- undefined: grpc.SupportPackageIsVersion6 和 undefined: grpc.ClientConnInterface 解决办法
- java classpath bat_tomcat启动批处理——setclasspath.bat | 学步园
- CentOS下安装postgresql
- 数据挖掘:探索性数据分析(EDA)(补充)
- 浏览器了解(一)浏览器大概流程
- mysql 总分区表限制_MySQL分区表的局限和限制详解
- [Linux源码分析]Linux内核架构
- 【贪玩巴斯】无线传感器网络(三)「Mac协议讲解」——2021-10-08
- 怎样停止魅族系统的推送服务器,实测可行!如何关闭魅族flyme系统的自带应用推送-魅蓝屏蔽设置...
- 开源GIS平台实战项目的总结
- 2.人工智能与机器学习的关系
- 生成扩散模型漫谈:DDIM = 高观点DDPM
- 小爱同学指令大全_小爱同学指令
热门文章
- bat 批处理切换到当前脚本所在文件夹
- 满纸荒唐言,一把辛酸泪--红楼一梦
- 生成建表脚本up_CreateTable
- interrupt 1 using 1
- ERROR 1045: Access denied for user: 'root@localhost' (Using password: YES)(转)
- 常用的Net Command
- 模拟退火粒子群优化算法控制程序
- 最简单的基于FFmpeg的AVfilter的例子-修正版
- jmeter最大请求数_jmeter单机最大并发数_动漫台
- python3占位符 中文_WxString:有没有使用Python 3-占位符实现字符串格式化的C/C++代码?...