李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
重载“+”与StringBuilder
Leefs
2019-12-16 PM
1924℃
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://lilinchao.com/archives/294.html
上一篇
字符串--String不可变
下一篇
Shiro简介
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
查找
Golang基础
MyBatis
Flink
Scala
FastDFS
稀疏数组
容器深入研究
Ubuntu
Kafka
排序
Netty
Hive
Java
字符串
BurpSuite
LeetCode刷题
Livy
Docker
数据结构和算法
Sentinel
Redis
国产数据库改造
SQL练习题
机器学习
Yarn
正则表达式
Jquery
Hbase
JavaSE
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭