1.学过C++的同学都知道,C++中的操作符是可以重载的;java的设计者认为这是比较“糟糕”的设计,所以只在java中保留的对字符串处理的+,+=重载操作符。
2.String类是final,不可变类,对字符串的拼接是经常会在代码里出来的:如下代码
package cn.demo;
public class TestString {
public static void main(String args[]){
String mysql="mysql";
String dataNames=mysql+"redis"+"maridb"+"oracle"+"mongodb";
System.out.println(dataNames);
}
}
3.来看看编译器对这段代码做的优化吧。
Compiled from "TestString.java"
public class cn.demo.TestString {
public cn.demo.TestString();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String mysql
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
10: aload_1
11: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #6 // String redismaridboraclemongodb
16: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: astore_2
23: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
26: aload_2
27: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
4.上面代码是使用了javap -c TestString 命令的结果:对代码进行了反汇编,了解过汇编的同学对上面的结果应该比较熟悉了;就算没有了解过汇编的同学,对上面的代码应该也是比较易懂的。
5.main的方法的第3行创建了StringBuilder对象,编译器利用String的可变配套类(StringBuilder)帮我们做了优化,不必要创建 一些无用的中间状态的字符串。
6.不能因为编译器帮我们做了优化就肆无忌惮的使用+来拼接字符串。有些复杂情况还是不太适合+,简单的字符串拼接可以使用+。