标题中所说的情况为StringBuilder.append(str + "abc")类似这种情况 在append中再次使用“+”进行拼接
StringBuilder在字符串拼接中是最快的,有些时候使用不当会影响效率,先看一个例子
public class Test {
public static void main(String[] args) {
String str = "a";
System.out.println(str + "b");//1
//System.out.println("a" + "b");//2
}
}
代码中1,2两部分输出结果都是一样的,但实际上第二个速度会快些,换句话说就是第二种比第一种高效。。。
这里也不能说是高效吧,应该是第一种写法有点多余了,,多干了一些活
使用javap命令可以很容易看清两者的区别 (使用方法 javap -c xxx.class)(如果提示找不到该命令,装一下jdk配一下环境变量即可)
注释掉2只显示1的效果 即打印System.out.println(str + "b");
javac Test.java
javap -c Test.class
Compiled from "Test.java"
public class Test {
public Test();
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 a
2: astore_1
3: getstatic #3 // Field java/lang/System.out:Ljava/
io/PrintStream;
6: new #4 // class java/lang/StringBuilder
9: dup
10: invokespecial #5 // Method java/lang/StringBuilder."<
init>":()V
13: aload_1
14: invokevirtual #6 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: ldc #7 // String b
19: invokevirtual #6 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
22: invokevirtual #8 // Method java/lang/StringBuilder.to
String:()Ljava/lang/String;
25: invokevirtual #9 // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
28: return
}
注释掉1只显示2的效果 即打印System.out.println("a" + "b");
javac Test.java
javap -c Test.class
Compiled from "Test.java"
public class Test {
public Test();
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 a
2: astore_1
3: getstatic #3 // Field java/lang/System.out:Ljava/
io/PrintStream;
6: ldc #4 // String ab
8: invokevirtual #5 // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
11: return
}
第一步都是先使用javac编译成class文件;
很容易看到第一种里面有一个StringBuilder,
具体步骤就是先创建一个字符串对象a;
然后创建对象StringBuilder,把字符串a添加到StringBuilder中;
然后创建字符串对象b,再把b添加到StringBuilder中;
最后调用StringBuilder中的toString得到字符串
但是第二种是直接创建字符串对象 ab,然后直接打印,省去了一部分操作,
因为第一种是变量+字符串,这里就会采用StringBuilder这种方式 (这原本是一种优化方式。。。)
同理来看看这段代码
public class Test {
public static void main(String[] args) {
String str = "a";
StringBuilder builder = new StringBuilder();
//builder.append(str + "b");//1
builder.append("a" + "b");//2
}
}
同样的道理 先看第一种builder.append(str + "b");
avac Test.java
javap -c Test.class
Compiled from "Test.java"
public class Test {
public Test();
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 a
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<
init>":()V
10: astore_2
11: aload_2
12: new #3 // class java/lang/StringBuilder
15: dup
16: invokespecial #4 // Method java/lang/StringBuilder."<
init>":()V
19: aload_1
20: invokevirtual #5 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
23: ldc #6 // String b
25: invokevirtual #5 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
28: invokevirtual #7 // Method java/lang/StringBuilder.to
String:()Ljava/lang/String;
31: invokevirtual #5 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
34: pop
35: return
}
再看第二种builder.append("a" + "b");
javac Test.java
javap -c Test.class
Compiled from "Test.java"
public class Test {
public Test();
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 a
2: astore_1
3: new #3 // class java/lang/StringBuilder
6: dup
7: invokespecial #4 // Method java/lang/StringBuilder."<
init>":()V
10: astore_2
11: aload_2
12: ldc #5 // String ab
14: invokevirtual #6 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: pop
18: return
}
最大的区别就是第一个里面的StringBuilder好多,,,一大堆,仔细看会发现第一种里面有两个地方new StringBuilder
第一个地方是源代码中就有new 第二个地方是在str + “b”的时候,原理的最开始一样
所以在StringBuilder的append里面就不要出现 变量 + 变量 或 + 字符串的情况为好!
=========================================================================================
javap参数展示
javap
Usage: javap <options> <classes>
where possible options include:
-help --help -? Print this usage message
-version Version information
-v -verbose Print additional information
-l Print line number and local variable tables
-public Show only public classes and members
-protected Show protected/public classes and members
-package Show package/protected/public classes
and members (default)
-p -private Show all classes and members
-c Disassemble the code
-s Print internal type signatures
-sysinfo Show system info (path, size, date, MD5 hash)
of class being processed
-constants Show static final constants
-classpath <path> Specify where to find user class files
-bootclasspath <path> Override location of bootstrap class files