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

kri*_*at_ 12 java string string-pool

我正在准备参加OCA SE 7考试,其中一些问题真的很棒(!).

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

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

在之后println方法执行,有多少String对象是那里的游泳池?

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

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

有人可以确认吗?


编辑:经过一些研究后,我发现在书中谈到"错误"并不公平; 作为一般提示:考试题目通常根据"以下代码"制定; 所以他们显然对简单的计算代码本身在本地做什么的简单计算感兴趣.因此,范围不允许检查println(boolean b)实现或编译器优化.很公平 :)

man*_*uti 14

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

System.out.println(false);
Run Code Online (Sandbox Code Playgroud)

最后打电话PrintStream#print(boolean):

public void print(boolean b) {
    write(b ? "true" : "false");
}
Run Code Online (Sandbox Code Playgroud)

这是在运行时发生,即在执行代码之后.但是,在字节码中存储的常量池的级别上,创建了一个字符串常量,它是"autumn"在包含您的main方法的类的类文件中.您可以通过运行以下命令来验证这一点:

javap -c -verbose ClassName
Run Code Online (Sandbox Code Playgroud)

  • 确定最后一句话?['PrintStream#print(boolean)`的实现](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/io/PrintStream.java#PrintStream .PRINT%28boolean%29). (6认同)
  • @krimat当你创建新的`String`时,字符串文字`"autumn"`已经在池中了.新创建的字符串未放置在池中. (4认同)
  • @krimat但是用于创建`String`的文字字符串被添加到常量池中. (3认同)
  • @krimat编译器肯定知道`autumn`与`summer`不同.因此,是的,它知道它应该生成`false`,使字符串评估短路. (3认同)
  • @krimat因为实际上编译器将行`System.out.println("autumn"=="summer");`转换为`System.out.println(false);`作为其优化过程的一部分.因此,生成的字节码不再引用"夏天"了. (2认同)