无法理解Java字符串文字是如何实现的

时间:2019-08-14 20:35:55

标签: java string jvm compiler-optimization stringbuilder

我正在学习StringBuider类。我已经在该站点和其他许多书籍中读到,当编译器遇到文字的“ +”运算符时,它会自动使用StringBuilder append的方法将它们串联起来。

似乎有些问题,因为将在运行时创建StringBuilder对象,但应该在编译时就已经获取String引用的字符串引用。

String s1 = "hello";  
String s2 ="bc"; 
int value = 22;

当编译器“满足”此代码时:

String s = s1+s2+22;

将其“更改”为:

String s = new StringBuilder().append("hello").append("bc").append(22).toString();

也许我误会了什么?

1 个答案:

答案 0 :(得分:6)

  

15.18.1. String Concatenation Operator +

     

实现可以选择一步执行转换和连接,以避免创建然后丢弃中间String对象。为了提高重复字符串连接的性能, Java编译器可以使用StringBuffer类或类似的技术来减少由以下对象创建的中间字符串对象的数量:表达式的计算。

就您而言,

String s1 = "hello";
String s2 ="bc";
int value = 22;

String r = s1 + s2 + value;

你会得到

INVOKESPECIAL java/lang/StringBuilder.<init> ()V
ALOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
ILOAD 3
INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;

重叠常量对象时

String r = "hello" + "bc" + 22;

你会得到

LDC "hellobc22"
ASTORE 2

  

当编译器“满足”此代码时:

String s = s1+s2+22;
     

将其“更改”为:

String s = new StringBuilder().append("hello").append("bc").append(22).toString();

不。可能会将其优化为

String s = new StringBuilder().append(s1).append(s2).append(value).toString();

,但是不能用s1代替"hello",因为不能保证变量将继续引用"hello"。该变量不是最终变量,因此可以重新分配。