为什么Oracle Java编译器更喜欢无参数StringBuilder构造函数?

为什么Oracle Java编译器更喜欢无参数StringBuilder构造函数?,java,javac,bytecode,compiler-optimization,Java,Javac,Bytecode,Compiler Optimization,纯粹出于兴趣,我一直在研究Oracle Java编译器如何处理Stringconcatenation,我看到了一些意想不到的东西 给定以下代码: 公共类StringTest{ 公共静态void main(字符串…参数){ String s=“Test”+getSpace()+“String。”; System.out.println(s.toString()); } //停止编译器将串联优化到最低限度 //单字符串文字。 静态字符串getSpace(){ 返回“”; } } 我预计编译器将对其

纯粹出于兴趣,我一直在研究Oracle Java编译器如何处理
String
concatenation,我看到了一些意想不到的东西

给定以下代码:

公共类StringTest{
公共静态void main(字符串…参数){
String s=“Test”+getSpace()+“String。”;
System.out.println(s.toString());
}
//停止编译器将串联优化到最低限度
//单字符串文字。
静态字符串getSpace(){
返回“”;
}
}
我预计编译器将对其进行优化,使其等效于:

String s=newstringbuilder(“Test”).append(getSpace())
.append(“字符串”).toString();
但它实际上可以归结为:

String s=new StringBuilder().append(“Test”).append(getSpace())
.append(“字符串”).toString();
我正在使用32位jdk1.7.055版本编译此文件。这是
javap-v-l
的输出:

公共类StringTest
源文件:“StringTest.java”
次要版本:0
主要版本:51
旗帜:ACC_公共、ACC_超级
固定池:
#1=Methodref#14.#25//java/lang/Object.“:()V
#2=类#26//java/lang/StringBuilder
#3=Methodref#2.#25//java/lang/StringBuilder。”“:()V
#4=字符串#27//测试
#5=Methodref#2.#28//java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#6=Methodref#13.#29//StringTest.getSpace:()Ljava/lang/String;
#7=字符串#30//字符串。
#8=Methodref#2.#31//java/lang/StringBuilder.toString:()Ljava/lang/String;
#9=Fieldref#32.#33//java/lang/System.out:Ljava/io/PrintStream;
#10=Methodref#34.#31//java/lang/String.toString:()Ljava/lang/String;
#11=Methodref#35.#36//java/io/PrintStream.println:(Ljava/lang/String;)V
#12=字符串#37//
#13=等级#38//StringTest
#14=类#39//java/lang/Object
#15=Utf8
#16=Utf8()V
#17=Utf8代码
#18=Utf8行号表
#19=Utf8主
#20=Utf8([Ljava/lang/String;)V
#21=Utf8 getSpace
#22=Utf8()Ljava/lang/String;
#23=Utf8源文件
#24=Utf8 StringTest.java
#25=名称和类型#15:#16/“”:()V
#26=Utf8 java/lang/StringBuilder
#27=Utf8测试
#28=名称和类型#40:#41//append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#29=名称和类型#21:#22//getSpace:()Ljava/lang/String;
#30=Utf8字符串。
#31=名称和类型#42:#22//toString:()Ljava/lang/String;
#32=类#43//java/lang/System
#33=名称和类型#44:#45//out:Ljava/io/PrintStream;
#34=类#46//java/lang/String
#35=类#47//java/io/PrintStream
#36=名称和类型#48:#49//println:(Ljava/lang/String;)V
#37=Utf8
#38=Utf8字符串测试
#39=Utf8 java/lang/Object
#40=Utf8追加
#41=Utf8(Ljava/lang/String;)Ljava/lang/StringBuilder;
#42=Utf8 toString
#43=Utf8 java/lang/System
#44=Utf8输出
#45=Utf8 Ljava/io/PrintStream;
#46=Utf8 java/lang/String
#47=Utf8 java/io/PrintStream
#48=Utf8 println
#49=Utf8(Ljava/lang/String;)V
{
公共测试();
旗帜:ACC_PUBLIC
LineNumberTable:
第2行:0
代码:
堆栈=1,局部变量=1,参数大小=1
0:aload_0
1:invokespecial#1//方法java/lang/Object。“:()V
4:返回
LineNumberTable:
第2行:0
公共静态void main(java.lang.String…);
标志:ACC_PUBLIC、ACC_STATIC、ACC_VARARGS
LineNumberTable:
第4行:0
第5行:27
第6行:37
代码:
堆栈=2,局部变量=2,参数大小=1
0:new#2//类java/lang/StringBuilder
3:dup
4:invokespecial#3//方法java/lang/StringBuilder。”“:()V
7:ldc#4//字符串测试
9:invokevirtual#5//方法java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
12:invokestatic#6//方法getSpace:()Ljava/lang/String;
15:invokevirtual#5//方法java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
18:ldc#7//String。
20:invokevirtual#5//方法java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
23:invokevirtual#8//方法java/lang/StringBuilder.toString:()Ljava/lang/String;
26:astore_1
27:getstatic#9//fieldjava/lang/System.out:Ljava/io/PrintStream;
30:aload_1
31:invokevirtual#10//方法java/lang/String.toString:()Ljava/lang/String;
34:invokevirtual#11//方法java/io/PrintStream.println:(Ljava/lang/String;)V
37:返回
LineNumberTable:
第4行:0
第5行:27
第6行:37
静态java.lang.String getSpace();
标志:ACC_静态
LineNumberTable:
第10行:0
代码:
堆栈=1,局部变量=0,
public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
}
new StringBuilder("Hello").append("World");
new StringBuilder().append("Hello").append("World");