李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
重载“+”与StringBuilder
Leefs
2019-12-16 PM
3156℃
0条
# 重载“+”与StringBuilder ### 前言 本篇开始讲述《Java编程思想》第13.2节,重载“+”与StringBuilder. ### 概念 重载:是指一个操作符在应用于特定的类时,被赋予了特殊的意义(用于String的“+”与“+=”是Java中仅有的两个重载过的操作符,而Java并不允许程序员重载任何操作符)。 #### 1.通过操作符“+”来连接String: ```java public class Concatenation { public static void main(String[] args) { String mango = "mango"; String s = "abc"+mango+"def"+47; System.out.println(s); } } ``` > 运行结果 ```java abcmangodef47 ``` 通过在cmd中运行如下指令对上方代码进行反编译: ```java javap -c Concatenation ``` 反编译运行结果如下: ```java public static void main(java.lang.String[]); Code: 0: ldc #2 // String mango 2: astore_1 3: new #3 // class java/lang/StringBuilder 6: dup 7: invokespecial #4 // Method java/lang/StringBuilder."
":()V 10: ldc #5 // String abc 12: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 15: aload_1 16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: ldc #7 // String def 21: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 24: bipush 47 26: invokevirtual #8 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 29: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 32: astore_2 33: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream; 36: aload_2 37: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 40: return } ``` 从上方代码可以看出,编译器帮我们自动引入了StringBuilder类,因为它更高效。 在示例中,编译器创建了一个StringBuilder对象,用以构造最终的String,并为每个字符串调用一次StringBuilder的append()方法,总计四次。最后调用toString()生成结果,并存为s(使用的命令是astore_2)。 #### 2. String优化比较 虽然编译器帮我们优化了String的性能,但是我们还是需要搞清楚在哪些方面做了优化,不能滥用。 **方法一:使用多个String对象** ```java public String implicit(String[] fields){ String result=""; for(int i=0;i
反编译结果 ```java public java.lang.String implicit(java.lang.String[]); Code: 0: ldc #2 // String 2: astore_2 3: iconst_0 4: istore_3 5: iload_3 6: aload_1 7: arraylength 8: if_icmpge 38 11: new #3 // class java/lang/StringBuilder 14: dup 15: invokespecial #4 // Method java/lang/StringBuilder."
":()V 18: aload_2 19: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 22: aload_1 23: iload_3 24: aaload 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_2 32: iinc 3, 1 35: goto 5 38: aload_2 39: areturn ``` > 结果分析 从第8行到第35行构成了一个循环体。 第8行:对堆栈中的操作数进行“大于或等于的整数比较运算”,循环结束时跳到第38行。 第35行:返回循环体的起始点(第5行)。 要注意的重点是:StringBuilder是在循环之内构造的,这意味着每经过循环一次,就会创建一个StringBuilder对象。 方法二:使用StringBuilder ```java public String explicit(String[] fields){ StringBuilder result = new StringBuilder(); for(int i=0;i
":()V 7: astore_2 8: iconst_0 9: istore_3 10: iload_3 11: aload_1 12: arraylength 13: if_icmpge 30 16: aload_2 17: aload_1 18: iload_3 19: aaload 20: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 23: pop 24: iinc 3, 1 27: goto 10 30: aload_2 31: invokevirtual #6 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 34: areturn ``` 与implicit()方法的反编译结果对比,不仅循环部分的代码更剪短、更简单,而且它只生成一个StringBuilder对象。显示地创建StringBuilder还允许你预先为其指定大小。如果你已经知道最终的字符串大概有多长,那预先指定StringBuilder的大小可以避免多次重新分配缓冲。 因此,当你为一个类编写toString()方法时,如果字符串操作比较简单,那就可以信赖编译器,它会为你合理地构造最终的字符串结果。但是,如果你要在toString()方法中使用循环,那么最好自己创建一个StringBulider对象,用它来构造最终的结果。 > 代码示例 ```java public class UsingStringBuilder { public static Random random = new Random(47); public String toStirng(){ StringBuilder result = new StringBuilder("["); for(int i=0;i<25;i++){ result.append(random.nextInt(100)); result.append(","); } result.delete(result.length()-2,result.length()); result.append("]"); return result.toString(); } public static void main(String[] args) { UsingStringBuilder usb = new UsingStringBuilder(); System.out.println(usb.toStirng()); } } ``` > 运行结果 ```java [58,55,93,61,61,29,68,0,22,7,88,28,51,89,9,78,98,61,20,58,16,40,11,22,] ``` 最终的结果是用append()语句一点点拼接出来的。
标签:
Java
,
Java编程思想
,
JavaSE
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://www.lilinchao.com/archives/294.html
上一篇
字符串--String不可变
下一篇
Shiro简介
取消回复
评论啦~
提交评论
栏目分类
随笔
2
Java
326
大数据
229
工具
35
其它
25
GO
48
NLP
8
标签云
散列
Spring
Spark Core
Map
MySQL
MyBatis
Elasticsearch
Flume
MyBatis-Plus
栈
Linux
持有对象
随笔
ClickHouse
Spark
Sentinel
SpringCloud
HDFS
字符串
序列化和反序列化
稀疏数组
人工智能
JVM
Git
Eclipse
国产数据库改造
Azkaban
并发编程
DataWarehouse
容器深入研究
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞