将 Java 在创建时更新字符串
Will Java update Strings on creation
由于字符串在 Java 中是不可变的,这会创建 3 个对象,还是会在内部只创建一个对象。
如何在 JVM 中执行,是否取决于 JVM 实现?
class Main{
public static void main(String[] args) throws Exception{
String s = "FirstString" + "SecondString" + "ThirdString";
}
}
如果上面的案例在编译时解决了,那么下面的案例是如何工作的。
class Main{
public static void main(String[] args) throws Exception{
String s = "FirstString" + "SecondString" + args[0];
}
}
在这个例子中
String s = "FirstString" + "SecondString" + "ThirdString";
用+
连接的3个常量字符串组成一个constant expression。这意味着编译器可以在编译时知道该表达式的确切结果,因此内联结果(即生成的 .class
文件看起来好像只有一个常量,内容为 FirstStringSecondStringThirdString
).
请注意,关于什么算作常量表达式的确切规则不是很直观,因此如果有兴趣,请查看 JLS 了解详细信息。
在
String s = "FirstString" + "SecondString" + someStringVariable;
第一个连接将“折叠”为简单的 "FirstStringSecondString"
,第三个连接将在运行时以“正常”方式完成。
非常复杂,导致池中的相关常量条目为 "FirstStringSecondString\u0001"
(请注意尾随 \u0001
以指示参数的位置)。但它仍然表明此表达式中的第一个连接在从 .java
到 .class
.
的编译过程中得到解决
这让我们意识到甚至
String s = "First" + "Second" + someStringVariable + "Last";
将被优化为单个操作,因为在这种情况下使用的常量是"FirstSecond\u0001Last"
。
由于字符串在 Java 中是不可变的,这会创建 3 个对象,还是会在内部只创建一个对象。
如何在 JVM 中执行,是否取决于 JVM 实现?
class Main{
public static void main(String[] args) throws Exception{
String s = "FirstString" + "SecondString" + "ThirdString";
}
}
如果上面的案例在编译时解决了,那么下面的案例是如何工作的。
class Main{
public static void main(String[] args) throws Exception{
String s = "FirstString" + "SecondString" + args[0];
}
}
在这个例子中
String s = "FirstString" + "SecondString" + "ThirdString";
用+
连接的3个常量字符串组成一个constant expression。这意味着编译器可以在编译时知道该表达式的确切结果,因此内联结果(即生成的 .class
文件看起来好像只有一个常量,内容为 FirstStringSecondStringThirdString
).
请注意,关于什么算作常量表达式的确切规则不是很直观,因此如果有兴趣,请查看 JLS 了解详细信息。
在
String s = "FirstString" + "SecondString" + someStringVariable;
第一个连接将“折叠”为简单的 "FirstStringSecondString"
,第三个连接将在运行时以“正常”方式完成。
"FirstStringSecondString\u0001"
(请注意尾随 \u0001
以指示参数的位置)。但它仍然表明此表达式中的第一个连接在从 .java
到 .class
.
这让我们意识到甚至
String s = "First" + "Second" + someStringVariable + "Last";
将被优化为单个操作,因为在这种情况下使用的常量是"FirstSecond\u0001Last"
。