Java的字符串连接符(+)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

点赞
收藏

评论区

加载中...

相关推荐

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

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

一篇文章带你了解JavaScript日期

日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用

Java的字符串连接符(+) - HelloWorld