hac*_*ddy 0 java string jvm string-concatenation
由于字符串在 Java 中是不可变的,这会创建 3 个对象,还是在内部仅创建一个对象。
在 JVM 中执行将如何发生,它是否取决于 JVM 实现?
class Main{
public static void main(String[] args) throws Exception{
String s = "FirstString" + "SecondString" + "ThirdString";
}
}
Run Code Online (Sandbox Code Playgroud)
如果上面的情况在编译时解决了下面的情况如何工作。
class Main{
public static void main(String[] args) throws Exception{
String s = "FirstString" + "SecondString" + args[0];
}
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中
String s = "FirstString" + "SecondString" + "ThirdString";
Run Code Online (Sandbox Code Playgroud)
连接+起来的 3 个常量字符串组成一个常量表达式。这意味着编译器可以在编译时知道该表达式的确切结果,因此将结果内联(即,结果.class文件看起来好像只有一个包含内容的常量FirstStringSecondStringThirdString)。
请注意,关于什么算作常量表达式的确切规则不是很直观,因此如果有兴趣,请查看 JLS 以获取详细信息。
在
String s = "FirstString" + "SecondString" + someStringVariable;
Run Code Online (Sandbox Code Playgroud)
第一个连接将被简单地“折叠” "FirstStringSecondString",第三个连接将在运行时以“正常”方式完成。
Java 9 中在运行时进行字符串连接的具体方式非常复杂,并且会导致池中的相关常量条目成为"FirstStringSecondString\u0001"(注意尾随\u0001指示参数的去向)。但它仍然表明该表达式中的第一个连接是在编译期间从.javato解析的.class。
这让我们意识到,即使
String s = "First" + "Second" + someStringVariable + "Last";
Run Code Online (Sandbox Code Playgroud)
将被优化为单个操作,因为在这种情况下使用的常量是"FirstSecond\u0001Last"。