在Java中连接字符串是否总会导致在内存中创建新字符串?

时间:2012-08-16 14:23:25

标签: java string compiler-construction string-concatenation

我有一个不符合屏幕宽度的长字符串。例如。

String longString = "This string is very long. It does not fit the width of the screen. So you have to scroll horizontally to read the whole string. This is very inconvenient indeed.";

为了便于阅读,我想到了这样写作 -

String longString = "This string is very long." + 
                    "It does not fit the width of the screen." +
                    "So you have to scroll horizontally" +
                    "to read the whole string." +
                    "This is very inconvenient indeed.";

但是,我意识到第二种方式是使用字符串连接,并且会在内存中创建5个新字符串,这可能会导致性能下降。是这样的吗?或者编译器是否足够智能,以确定我需要的只是一个字符串?我怎么能避免这样做?

3 个答案:

答案 0 :(得分:39)

  

我意识到第二种方式是使用字符串连接,并且会在内存中创建5个新字符串,这可能会导致性能下降。

不,不会。由于这些是字符串文字,因此将在编译时对它们进行评估,并且将仅创建一个字符串。这在Java Language Specification #3.10.5

中定义
  

长字符串文字总是可以分解成更短的部分,并使用字符串连接运算符+作为(可能是带括号的)表达式写入   [...]
  此外,字符串文字始终引用类String的相同实例。

     
      
  • 通过常量表达式计算的字符串(第15.28节)在编译时计算,然后将其视为文字。
  •   
  • 在运行时通过串联计算的字符串是新创建的,因此是不同的。
  •   

测试:

public static void main(String[] args) throws Exception {
    String longString = "This string is very long.";
    String other = "This string" + " is " + "very long.";

    System.out.println(longString == other); //prints true
}

但是,下面的情况是不同的,因为它使用了一个变量 - 现在有一个连接并且创建了几个字符串:

public static void main(String[] args) throws Exception {
    String longString = "This string is very long.";
    String is = " is ";
    String other = "This string" + is + "very long.";

    System.out.println(longString == other); //prints false
}

答案 1 :(得分:8)

  

在Java中连接字符串是否总是导致在内存中创建新字符串?

不,它并不总是这样。

如果连接是一个编译时常量表达式,那么它由编译器执行,并将生成的String添加到已编译的类常量池中。在运行时,表达式的值是与常量池条目对应的实习String

这将在你问题的例子中发生。

答案 2 :(得分:1)

请根据您的输入检查以下代码段:

String longString = "This string is very long. It does not fit the width of the screen. So you have to scroll horizontally to read the whole string. This is very inconvenient indeed.";

String longStringOther = "This string is very long. " + 
        "It does not fit the width of the screen. " +
        "So you have to scroll horizontally " +
        "to read the whole string. " +
        "This is very inconvenient indeed.";

System.out.println(" longString.equals(longStringOther) :"+ longString.equals(longStringOther));      
System.out.println(" longString == longStringother : " + (longString == longStringOther ));

<强>输出:

longString.equals(longStringOther):true
longString == longStringother:true

第一个案例:两个字符串相等(内容相同)

第二种情况:显示连接后只有一个字符串。 因此只创建了一个字符串。