Java 使用println的池中的字符串计数
我正在准备亚奥理事会SE7考试,其中一些问题真的很棘手 在我使用的其中一本书中,我发现了一个错误,所以我想确认以下内容Java 使用println的池中的字符串计数,java,string,string-pool,Java,String,String Pool,我正在准备亚奥理事会SE7考试,其中一些问题真的很棘手 在我使用的其中一本书中,我发现了一个错误,所以我想确认以下内容 public static void main(String... args) { String autumn = new String("autumn"); // line one System.out.println("autumn" == "summer"); // line two } 执行println方法后,池中有多少String对象
public static void main(String... args) {
String autumn = new String("autumn"); // line one
System.out.println("autumn" == "summer"); // line two
}
执行println
方法后,池中有多少String
对象
我的理解是:
-第一行没有将字符串添加到池中
-第二行创建“秋”和“夏”,并将它们添加到池中
所以书中的正确答案是2
然而,我也认为。。。因为我被认为是偏执狂的考试问题。。。还将创建字符串“false”并将其添加到池中。。。所以我认为3应该是正确的答案。。。或者其他的黑魔法会像。。。默认情况下,JVM已经将“true”和“false”放入池中了,还是什么
有人能确认一下吗
编辑:
经过一些研究,我发现我在书中提到“错误”是不公平的;作为一般提示:试题通常是按照“以下代码”来制定的;因此,他们显然对代码本身在本地执行的简单计算感兴趣。因此,该范围不允许检查
println(布尔b)
实现或编译器优化。很公平:)它应该是两个字符串:“秋”
和“假”
。第一行由第一行创建。第二行由第二行创建,因为编译器会将其优化为:
System.out.println(false);
最后调用PrintStream\print(布尔)
:
这是在运行时发生的,即代码执行后。但是,在字节码中存储的常量池级别,只创建了一个字符串常量,它是包含main
方法的类的类文件中的“秋
”。您可以通过运行以下命令来验证这一点:
javap -c -verbose ClassName
true和false不是字符串对象,因此它们不计算。尽管考题应该很棘手,但它的目标是检查对一般概念的理解。在这种情况下:在类加载期间(在运行之前),字符串文本被加载到常量池。所以“秋”和“夏”将在不断的池中 这里很好地描述了这一点:
PrintStream#print(boolean)的实现是:write(b?“true”:“false”)代码>,因此它将向池中添加“true”
和“false”
。(#println(boolean)
调用#print(boolean)
)谢谢@Tom:这就是我正在研究的实现,但我想只有“true”或“false”会被创建,因为表达式是短路的,没有什么有趣的问题。如果加载该类,它可能会添加所有字符串文本,但我不确定。也许验证的方法对你有帮助。@BalintDomokos它很重要,因为System.out
是一个PrintStream
@BalintDomokos好吧,如果OP是对的,这本书提出了一些棘手的问题,读者可能应该学会阅读库实现,那么我想它在这里很重要。但我不知道这本书。确定最后一句吗@krimat但是用于创建字符串的文本字符串已添加到常量池中。@krimat当您创建新的字符串时,字符串文本“秋”
已在池中。新创建的字符串未放在池中。@krimat,因为编译器实际上会转换行System.out.println(“秋”=“夏”)编码>输入系统输出打印项次(假)代码>作为其优化过程的一部分。因此,生成的字节码不再引用“summer”
。@krimat编译器肯定知道秋
与summer
不同。因此,是的,它知道它应该生成false
,使字符串计算短路。。。
javap -c -verbose ClassName