字符串操作是程序设计中最常见的行为,Java语言中使用最广泛的字符串类是String类(还不知道String类的同学请看我之前的博客)。很多初级程序设计,只使用了String类,但是,当我们想提升程序运行效率,提升程序设计水平的时候,我们需要深度理解另一个字符串类SringBuilder。本文利用了反编译工具,从JVM字节码的视角,深度探讨了String和StringBuilder的区别和应用场景。
1、不可变的String
查看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。
2、StringBuilder类简介
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);
}
}
3、String和StringBuilder使用场景
在前面,我们分析了,当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对象,显然提高了程序的运行效率。
4、总结
- String是不可变字符串
- StringBuilder是可变字符串
- 单次字符串拼接,建议使用String类,利用JVM自动优化
- 多次循环拼接,建议使用StringBuilder,提高程序运行效率
/******************************************************************************************
* 作者简介:本人擅长C++、Java和算法开发,具有7年一线开发经验,目前在某人工智能公司任技术总监。
* 欢迎关注我的公众号【码农充电站】,公众号里为大家准备了编程干货和精品项目源码
* 公众号:码农充电站
* 作者微信:it1529577
*****************************************************************************************/