25

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

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 个新字符串,这可能会导致性能下降。是这样吗?或者编译器是否足够聪明,可以找出我真正需要的只是一个字符串?我怎么能避免这样做呢?

4

3 回答 3

44

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

不,不会的。由于这些是字符串文字,它们将在编译时进行评估,并且只会创建一个字符串。这在Java 语言规范 #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
}
于 2012-08-16T14:27:32.370 回答
8

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

不,它并不总是这样做。

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

这将发生在您问题的示例中。

于 2012-08-16T14:28:27.260 回答
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

第一种情况:两个字符串相等(内容相同)

第二种情况:表明连接后只有一个字符串。所以只创建了一个字符串。

于 2013-01-14T07:40:08.643 回答