字符串操作是程序设计中最常见的行为,Java语言中使用最广泛的字符串类是String类(还不知道String类的同学请看我之前的博客)。很多初级程序设计,只使用了String类,但是,当我们想提升程序运行效率,提升程序设计水平的时候,我们需要深度理解另一个字符串类SringBuilder。本文利用了反编译工具,从JVM字节码的视角,深度探讨了String和StringBuilder的区别和应用场景。
查看JDK文档可知,String对象是不可变的,如果对字符串进行拼接操作,每次拼接,都会构建一个新的String对象。看看下面的代码:
public class StringDemo {
public static void main(String[] args) {
String s1 = "hello";
s1 = s1+"world";
System.out.println(s1);
}
}
为了证明上面代码中拼接后的s1到底是不是一个新的String对象,可以使用JDK自带的工具Javap来反编译以上代码。在cmd中输入如下命令:
javap -c StringDemo
反编译出来的文件是汇编语言,即使你完全不懂汇编语言也无须担心,我已经为这份反编译文件增添了详细的注释,你一定能看懂,附上反编译文件源码和注释:
从反编译的代码中,我们可以知道,编译器为我们自动创建了一个StringBuilder对象,用来拼接字符串,在String拼接的时候,调用StringBuilder的append()方法,最后调用StringBuilder的toString()方法返回结果,赋值给s1。
StringBuilder是一个可变的字符串类,我们可以把它看成一个容器,这里的可变指的是StringBuilder对象中的内容是可变的。我们用一段有关StringBuilder的代码案例,介绍StringBuilder类的用法:
public class StringBuilderDemo {
public static void main(String[] args) {
//无参构造方法
StringBuilder sb = new StringBuilder();
sb.append("hello");//拼接字符串
sb.append("world");
String s1 = sb.toString(); //StringBuilder转换为字符串
System.out.println(s1);
//有参构造方法
StringBuilder sb2 = new StringBuilder("hello world");
String s2 = sb2.toString();
System.out.println(s2);
}
}
在前面,我们分析了,当String字符串拼接时,编译器会自动优化,自动创建StringBuilder。可能你会觉得可以随意使用String对象,反正编译器会为你自动优化性能。但是,有一个疑问,我们必须解决:编译器到底可以为我们优化到什么程度?我们来更深入的看一看这个问题,请看下面的例子:假如现在要把一个String数组拼接成一个字符串,现在有两种写法
public class StringBuilderDemo {
public String implicit(String[] fields){
String result = "";
for (int i = 0; i <fields.length ; i++) {
result += fields[i];
}
return result;
}
public String explicit(String[] fields){
StringBuilder result = new StringBuilder();
for (int i = 0; i <fields.length ; i++) {
result.append(fields[i]);
}
return result.toString();
}
}
implicit方法每次for循环都会创建一个新的StringBuilder对象,而explicit方法,只需要创建一个StringBuilder对象,显然提高了程序的运行效率。
/******************************************************************************************
* 作者简介:本人擅长C++、Java和算法开发,具有7年一线开发经验,目前在某人工智能公司任技术总监。
* 欢迎关注我的公众号【码农充电站】,公众号里为大家准备了编程干货和精品项目源码
* 公众号:码农充电站
* 作者微信:it1529577
*****************************************************************************************/
?
系列文章目录 文章目录 系列文章目录 前言 一、链表的中间结点 1.题目描述 2.解...
Lambda表达式 λ 希腊字母表中排序第十一位的字母英语名称为Lambda 避免匿名内部...
生产上为了高效地查询数据库中的数据,我们常常会给表中的字段添加索引,大家是...
简单了解过Redis的小伙伴应该都知道Redis常被当做缓存。那为什么要选这个nosql型...
本文实例总结了PHP实现二维数组(或多维数组)转换成一维数组的常见方法。分享给...
在去年下半年的win 10功能更新中,新版Edge已经成为默认浏览器,很多用户已经开...
语法:marquee /marquee 使用移动属性marquee,不仅仅可以舞动你的文字,还可以...
轻巧而直接,nano 提供了一个简单、直观的编辑器,没有额外的麻烦。 许多 Linux ...
项目背景 因为项目采用前后端完全分离方案,所以,无法使用常规的微信授权登录作...
索引优化的目的主要是让索引不失效,走正确的索引,今天主要分享的是最近整理的...