将 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"