开发过程中,遇到的问题,特此记录一下,也想着分享出来,免得不了解的朋友疑惑。
我们都知道 java String + 底层是通过一个 StringBuilder 实现的拼接,但当需要拼接的两个 String 常量,有一个 String 为空字符串(即:"")时,那会不会是一种特殊情况呢?带着这个疑问,我们去看下下面小实验,
首先创建了一个TestDemo类,代码如下:
public class TestDemo{
String a;
String x = "Anthony";
public TestDemo(){}
public void test1() {
if (true){
a = x;
} else {
a = "" + x;
}
}
public void test2() {
if (false){
a = x;
} else {
a = "" + x;
}
}
public void test3() {
if (false){
a = x;
} else {
a = "Cidy" + x;
}
}
}
通过javac、javap命令编译一下,查看下cpu会执行到的指令,
test1() 函数指令:
public void test1();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: aload_0
2: getfield #3 // Field x:Ljava/lang/String;
5: putfield #4 // Field a:Ljava/lang/String;
8: return
LineNumberTable:
line 10: 0
line 14: 8
test2() 函数指令:
public void test2();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: new #5 // class java/lang/StringBuilder
4: dup
5: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V
8: ldc #7 // String
10: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
13: aload_0
14: getfield #3 // Field x:Ljava/lang/String;
17: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
23: putfield #4 // Field a:Ljava/lang/String;
26: return
LineNumberTable:
line 20: 0
line 22: 26
test3() 函数指令:
public void test3();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: new #5 // class java/lang/StringBuilder
4: dup
5: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V
8: ldc #10 // String Cidy
10: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
13: aload_0
14: getfield #3 // Field x:Ljava/lang/String;
17: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
23: putfield #4 // Field a:Ljava/lang/String;
26: return
LineNumberTable:
line 28: 0
line 30: 26
对 test1 和 test2 指令比较

它们的比较,主要区别在于执行了“+”操作后,会创建 StringBuilder 对象,这个时候会增加内存的开销;
对 test2 和 test3 指令比较

它们的比较,主要想看空字符串与非空字符串对内存的影响。整体来看,除了创建的 String 字符串占用的字节数不同外,其他的完全相同;
综合以上内容,我们了解到只要执行 String + 操作,底层就会创建一个 StringBBuilder 对象来处理字符串的拼接。所以当我们在开发的过程中,尽量避免空字符串执行 String + 拼接操作。
网友评论