带有 println 的池中的字符串计数

String count in the pool with println

我正在准备 OCA SE 7 考试,其中一些问题真的(!)棘手。

在我使用的其中一本书中我发现了一个错误,所以我想确认以下内容...

public static void main(String... args) {
    String autumn = new String("autumn");      // line one
    System.out.println("autumn" == "summer");  // line two
}

println方法执行后,池中有多少String个对象?

据我了解: - 第一行不将字符串添加到池中 - 第二行创建 "autumn" 和 "summer" 并将它们添加到池中 所以书上的正确答案是2。

但是,我也认为...因为我应该对考试问题偏执...字符串 "false" 也已创建并添加到池中...所以我认为 3 应该是正确的答案......或者是否发生了其他一些黑魔法...... "true" 和 "false" 默认情况下已经被 JVM 放入池中或什么?......

有人可以确认一下吗?


编辑: 经过一些研究,我发现在书中谈论 'error' 对我来说是不公平的;作为一般提示:考试问题通常根据 'the following code' 制定;所以他们显然对代码本身在本地做什么的简单老式简单计算感兴趣。因此,范围不允许检查 println(boolean b) 实现或编译器优化。很公平:)

它应该是 2 个字符串:"autumn""false"。第一个由第一行创建。第二个是由第二行创建的,因为编译器会将其优化为:

System.out.println(false);

最终调用 PrintStream#print(boolean):

public void print(boolean b) {
    write(b ? "true" : "false");
}

这是运行时,即代码执行后发生的情况。但是,在字节码中存储的常量池级别,仅创建了 1 个字符串常量,即 "autumn" classclass 的文件,其中包含您的 main 方法。您可以通过 运行:

验证这一点
javap -c -verbose ClassName

true和false不是String对象,所以不算。尽管考试问题应该很棘手,但它的目标是检查对一般概念的理解。在这种情况下:在 class 加载期间(在 运行 之前),字符串文字被加载到常量池中。所以 "autumn" 和 "summer" 将在常量池中。

这里描述得很好: http://www.javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html