【问题标题】:Does Java Compiler include String Constant Folding?Java 编译器是否包含字符串常量折叠?
【发布时间】:2012-01-24 19:01:50
【问题描述】:

我发现Java supports constant folding of primitive types,但是Strings 呢?

示例

如果我创建以下源代码

out.write(""
        + "<markup>"
        + "<nested>"
        + "Easier to read if it is split into multiple lines"
        + "</nested>"
        + "</markup>"
        + "");

编译后的代码中有什么内容?

组合版本? out.write("&lt;markup&gt;&lt;nested&gt;Easier to read if it is split into multiple lines&lt;/nested&gt;&lt;/markup&gt;");

还是效率较低的运行时串联版本? out.write(new StringBuilder("").append("&lt;markup&gt;").append("&lt;nested&gt;").append("Easier to read if it is split into multiple lines").append("&lt;/nested&gt;").append("&lt;/markup&gt;").append(""));

【问题讨论】:

  • 字符串连接比写入设备快大约 100 倍。如果没有(但确实如此),那真的没多大关系
  • 我刚刚在我的笔记本电脑上测试了它,它慢了 50 倍。
  • 这实际上是 JLS 要求的行为。 /javap -c可以看到生成的代码。
  • 不知道的朋友,JLS = Java Language Specification

标签: java string constants compiler-optimization constantfolding


【解决方案1】:

这是一个简单的测试:

public static void main(final String[] args) {
    final String a = "1" + "2";
    final String b = "12";        

    System.out.println(a == b);
}

输出:

true

所以,是的,编译器会折叠。

【讨论】:

    【解决方案2】:

    将使用组合版本
    编译器会自动对其进行优化并将其放入字符串池中。

    您可以通过编写此行轻松证明此行为。

    System.out.println("abc" == "a" + ("b" + "c")); // Prints true
    

    这打印为真,意味着它们是相同的对象。这是因为两件事:

    1. 编译器将"a" + ("b" + "c") 优化为"abc"
    2. 编译器将所有字符串文字放入字符串池中。这种行为称为String Interning

    【讨论】:

    • 此行为的第一部分称为常量表达式求值。
    【解决方案3】:

    它有效地转化为: out.write("&lt;markup&gt;&lt;nested&gt;Easier to read if it is split into multiple lines&lt;/nested&gt;&lt;/markup&gt;");

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-13
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      相关资源
      最近更新 更多