Java的字符串连接符(+)

Wesley13
• 阅读 613

在Java中字符串是一个常用的东西,而其一个常用的操作是字符串的拼接,Java对此提供了一种非常直观的操作方式——即 + 操作符。

String str0 = "a";
String str1 = str0 + "b";

如上的程序片段就实现了一个字符串的拼接,可以看到整个描述非常简洁,一目了然。学习Java的时候,这是接触到的第一种拼接字符串的方式,先入为主的印象会让你在以后需要拼接字符串时第一时间想到它,但是,你会听到大家都说:拼接大量的字符串时使用StringBuilder更好,这是为什么呢?

让我们看看编译器是怎么处理 + 操作符的。下面是上一个程序片段编译后的字节码指令:

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #2                  // String a
       2: astore_1
       3: new           #3                  // class java/lang/StringBuilder
       6: dup
       7: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
      10: aload_1
      11: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      14: ldc           #6                  // String b
      16: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      22: astore_2
      23: return
}

通过阅读这段字节码,可以发现,我们的**+**拼接操作实际上被编译器理解成了这个样子:

String str0 = "a";
StringBuilder sb = new StringBuilder();
sb.append(str0).append("b");
String str1 = sb.toString();

中间多出来了一个StringBuilder对象,这是一个临时对象。

假设我们现在有这样一段程序片段:

String str0 = "a";
for (int i = 0; i < 10000; i++) {    
      str0 += "a";
}

再来看看编译后的字节码:

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #2                  // String a
       2: astore_1
       3: iconst_0
       4: istore_2
       5: iload_2
       6: sipush        10000
       9: if_icmpge     38
      12: new           #3                  // class java/lang/StringBuilder
      15: dup
      16: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
      19: aload_1
      20: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      23: ldc           #2                  // String a
      25: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      28: invokevirtual #6                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      31: astore_1
      32: iinc          2, 1
      35: goto          5
      38: return
}

5~35是我们的循环体,在循环体里面,每次拼接都会生成一个StringBuilder的临时对象,那么这个程序片段执行下去就会产生10000个StringBuilder的临时对象,这10000个临时对象都是必要的吗?显然不是,我们可以在循环体外直接创建一个StringBuilder对象,然后在循环体中通过append方法拼接字符串,这样就省下了创建并回收10000个临时对象的消耗。

所以,在需要拼接大量字符串时,还是使用StringBuilder对象为好。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
LeeFJ LeeFJ
1年前
Foxnic-SQL (13) —— 外部SQL与SQL模版
首先,大多数时候,我们的第一反应是用字符串去拼接SQL语句,这说明字符串拼接方式其实是最直观的。其次,使用对象化的方式拼接SQL,还是有其局限性,大量的SQL文本也不宜直接写在Java类中。所以,FoxnicSQL将原本要写在Java类中的SQL语句放到一个外部文件中,每个语句用一个ID去标识,在SQL执行时,只要指定ID就可以了。在此基础上,FoxnicSQL加入了模板引擎、SQL语句置换、热加载等特性,使其变得更加好用。
Java服务总在半夜挂,背后的真相竟然是... | 京东云技术团队
最近有用户反馈测试环境Java服务总在凌晨00:00左右挂掉,用户反馈Java服务没有定时任务,也没有流量突增的情况,Jvm配置也合理,莫名其妙就挂了