【发布时间】:2014-01-10 15:39:49
【问题描述】:
我正在学习并准备参加 Java SE 6 认证。我正在使用 Kathy Sierra 和 Bert Bates 的书“Sun Certified Programmer for Java 6 Study Guide”。我实际上是在字符串、I/O 和解析方面。
他们提供了一个我可能期望在考试中看到的那种恶魔般的字符串问题的例子:
String s1 = "spring ";
String s2 = s1 + "summer ";
s1.concat("fall ");
s2.concat(s1);
s1 += "winter ";
System.out.println(s1 + " " + s2);
输出是什么?对于额外的功劳,有多少 String 对象以及如何 在 println 语句之前创建了许多引用变量?
答案:这段代码片段的结果是spring winter spring 夏天。有两个参考变量,s1 和 s2。有一个 总共创建了八个 String 对象,如下所示:“spring”、“summer” (迷路)、“春夏”、“秋天”(迷路)、“春秋”(迷路)、“春天” 夏春”(丢失)、“冬”(丢失)、“春冬”(此时 “弹簧”丢失)。八个 String 对象中只有两个没有丢失 在这个过程中。
我在标题中的问题非常具体。如您所见,他们说总共有 8 个String 对象,但是,在 println 方法调用时会发生什么?它传递一个 String 对象引用作为参数,因此 s1 加上 s2 的值应该创建另一个 String 对象,因为它是不可变的,将计数增加到 9。
但是(可能更多)不应该在 s1 和 s2 的值之间的空字符串 (" ") 创建其他对象,将计数增加到 10 吗?
他们这样做的时候很重要:
s1.concat("下降");
那么,为什么不这样:
s1.concat(s1 + " " + s2);
或真正的,这个:
System.out.println(s1 + " " + s2);
【问题讨论】:
-
我猜“在 println 语句之前”是指在整行之前,而不是在输入 println 方法之前。
-
请记住,编译器也会优化字符串(如果可以的话)。如果你有 String s1 = "spring" + " " + "summer",编译器会将它变成一个。不确定编译器是否足够聪明以优化第 2 行 - 因为您使用的是变量而不是“spring”。
-
其实,“spring”、“summer”、“fall”和“winter”并不是在上面创造出来的——它们是从原始的软泥中产生的。
-
当然,这两个 concat 操作在创建字符串时完全是噪音——它们没有任何效果。