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

标签 java string jvm compiler-optimization stringbuilder

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

这似乎有点问题,因为将在运行时创建StringBuilder对象,但是应该在编译时获取String引用的串联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();


也许我误会了什么?

最佳答案

15.18.1. String Concatenation Operator +

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


就你而言

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"。该变量不是最终变量,因此可以重新分配。

关于java - 无法理解Java字符串文字是如何实现的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57501710/

相关文章:

string - 错误WAR包装错误:字符串索引超出范围:11

r - 拆分字符串最后一个分隔符

java - ThreadMXBean.getThreadAllocationBytes(long id) 中包含哪些 JVM 运行时数据区域

Java - 当创建类关闭时对象引用是否会被销毁?

java - 从 Java 中的字符串数组中删除空字符串元素

java - 如何检查类名是否有效?

java - Intent 另一个布局的运行时错误

Java system.out.format 想要 Object[] 数组而不是简单的变量?

javac 生成一个桥接方法,其中包含指向抽象方法的 invokespecial 指令

java - 停止和启动计时器