java 字符串拼接_不能用 + 拼接字符串?这次我要吊打面试官

转载:https://mp.weixin.qq.com/s/7xEjUyGjazL4Rm1xTIoRAw

作者:Java技术栈

我们做 Java 程序员以来,不管是工作当中,还是面试过程中,都知道:字符串拼接不能用 String,要用 StringBuilder 或者是 StringBuffer,以至于它们都被滥用了。

StringBuilder、StringBuffer 简称:SB,下文统一用 SB 代替。

SB它们都是可变的字符串,它们之间的区别也是 Java 初中级面试战场上出现几率十分高的一道题,上场率没有 90% 也有 80% 吧。

这两个的具体区别请看这篇文章:StringBuffer 和 StringBuilder 的 3 个区别。

我们反过来想下,String真的是不可变的么?不一定,看下这篇:Java 中的 String 真的是不可变的吗?

当然,本文不是讨论字符串可变与不可变的问题,而是讨论:字符串拼接一定要用SB 吗?为什么不能用 + ?能不能用 + ?什么时候可以用 + ?

为什么不能用 + 号拼接字符串?我不服,接下来我要吊打面试官!

什么时候不能用 `+`

通过多个表达式完成一个字符串拼接操作。

dfbbb267ce94e7d9d2d9c4ba5e38e80b.png

字节码如下:

// access flags 0xAprivate static test2()VL0LINENUMBER 14 L0LDC "www."ASTORE 0L1LINENUMBER 15 L1ALOAD 0ASTORE 1L2LINENUMBER 16 L2NEW java/lang/StringBuilderDUPINVOKESPECIAL java/lang/StringBuilder. ()VALOAD 1INVOKEVIRTUAL 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 1L3LINENUMBER 17 L3NEW java/lang/StringBuilderDUPINVOKESPECIAL java/lang/StringBuilder. ()VALOAD 1INVOKEVIRTUAL 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 1L4LINENUMBER 18 L4RETURNL5LOCALVARIABLE www Ljava/lang/String; L1 L5 0LOCALVARIABLE str Ljava/lang/String; L2 L5 1MAXSTACK = 2MAXLOCALS = 2

不会查看字节码的,看这里:3种骚操作,教你查看 Java 字节码,看这一篇就会了。

观察下,NEW java/lang/StringBuilder 出现了两次,是因为我们在代码中拼接了两次,也就是说每一次拼接操作都会创建一次 StringBuilder。

如果我们是在一个循环中进行字符串拼接,那是不是一次拼接就要创建一个StringBuilder?

wtf……这哪能接受!频繁创建对象是有性能开销的,这也是为什么我们常说的字符串不能用 + 拼接,而要用那两个 SB 拼接了。

什么时候可以用 `+`

直接将三个字面量的字符串拼接成一个字符串。

734b3a4975953fab5492e5cc85941d78.png

字节码如下:

6ac007af89b56676a0b6465bec3ce64a.png

从字节码看出,没有任何创建 StringBuilder 的指令,直接从常量池进行取出一个完整的字符串:www.javastack.com。很明显,这是 Java 编译器对代码进行了优化。

所以,通过这个示例告诉你,在这种情况下是可以用 + 号进行字符串拼接的。

这个示例可以演变成我们实际工作当中的某个 SQL 语句拼接的案例,如:

3bfe96146ba769229b2f9fb2bc0fd9c1.png

别说这样不行,这样是行的。

但你要是换成这样就不行了:

e3addc71a1bfb320d58e36dcb893498b.png

这样又回到创建多个 StringBuilder 的时候了。

也就是说,在一个表达式中完成字符串拼接是可以用 + 号完成的,因为编译器已经做了优化。

小结一下

你只需要记住这两点:

1、在循环和多个表达式中不能 +,频繁创建 SB 性能影响;

2、在单个表达式中可以用 +,编译器直接做了优化;

老铁们,都搞清楚了?

这个观点有没有被误解很久?

下次面试,把这篇内容亮出来,吊打面试官,没问题的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值