关于+与StringBuilder的那些事

关于+与StringBuilder的那些事

最近在看Thinking in Java,刚好看到这一块,就来记录下自己的一些体会。

StringBuilder的使用

因为String类是一个典型的不可变类,当实例对象创建后,就不能再被改变。如需进行字符串的操作,可以使用StringBuilder或StringBuffer来进行拼接,两者的区别是后者是前者的线程安全版本,若无特殊需求,可直接选择StringBuilder使用,如下:

StringBuilder sb=new StringBuilder();
sb.append(new char[]{'W','o','r'},0,3);//[0,3)
sb.insert(0,"Hello ");
sb.append("ld!");
System.out.print(sb.toString());//Hello World!

StringBuilder中有很多的方法,如append用来拼接,insert用来插入,还可以根据index来修改单个字符,功能十分强大。

Java中的+号

在java中,不支持对运算符的自定义重载,所以+应该就算的上是唯一一个重载过的运算符了吧。用+也可以进行字符串的拼接,如下:

String s1="Hello ";
String s2="Wor";
String s3="ld!";
String s=s1+s2+s3;
System.out.println(s=="Hello World!");//true

使用起来十分的方便,那么因为String的实例对象都是不可变的,这样的表达式会不会产生很多的中间量呢?我们可以通过java自带的工具javap来查看这段代码生成的字节码:

javap -c 文件名

关于+与StringBuilder的那些事_第1张图片

可以看到,通过编译后,上面那段代码被自动优化成了使用StringBuilder来进行拼接,所以效率可以保证。
但是,是不是因为这样,在拼接字符串的时候,我们就可以使用+来直接代替StringBuilder了呢?先不要着急下结论,我们再来看一个例子:

String s=null;
for(int i=0;i<5;i++)
s=s+i;
System.out.println(s);

我们看看这段代码编译后是什么样子呢:
关于+与StringBuilder的那些事_第2张图片
看到了什么,StringBuilder的创建居然在循环内部!!这就有些恐怖了,因为这代表着你有多少次的循环就会创建多少个StringBuilder对象。所以,如果要通过循环来创建字符串的话,就不能通过+来直接拼接了,一定要记着使用StringBuilder。

StringBuilder需要避免的一种用法

StringBuilder sb=new StringBuilder();
String a="1";
String b="2";
sb.append(a+b);

我们已经知道了+的操作在编译时会自动优化成Stringbuilder来进行操作,那么上面这个例子中a+b还会新创建一个StringBuilder对象吗?答案是会:
关于+与StringBuilder的那些事_第3张图片
所以实际开发中应尽量避免上述写法,使用append()进行拼接。

最后再说两句

之前在网上看到过一个评论说下面这样的代码可以在编译时就可以确定String的值,我直接就看蒙了(因为自己学的太渣。。):

String a="a";
String b="b";
String d="d";
String c = a+b+d;

特地试了一下,发现并这段代码没有像上面说的一样,在编译时就确定c的值,而是创建了StringBuilder进行拼接。之后又想了下,估计可能是想说的是下面这种情况:

final String a="a";
final String b="b";
final String d="d";
String c = a+b+d;

因为a、b、d都是final修饰的,所以在编译期就可以确定值,因此就会进行“宏替换”,所以编译时就相当于根本没有a、b、d变量一样,等价于:

String c="a"+"b"+"d";

你可能感兴趣的:(java基础)