在Java中编译时是否完成了字符串实习? [英] Is string interning done at compile time in Java?

查看:88
本文介绍了在Java中编译时是否完成了字符串实习?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对字符串实习如何在Java中工作感到困惑。我写的时候:

I am really confused with how string interning works in Java. When I write:

String a = "ABC";
String b = "ABC";

if (a==b)
    System.out.println("Equal");

编译器编译时是否将字符串文字ABC存储到字符串常量池中?

Does the compiler store the string literal "ABC" into the string constant pool at compile time?

这听起来不合逻辑,因为我认为字符串常量池是由JVM在运行时创建的,如果在编译时完成,我不知道它是如何实现的Java编译器甚至不调用JVM。

That sounds illogical, because I thought the string constant pool was created by the JVM at runtime, and I don't see how that is possible if it is done at compile time since the Java compiler does not even invoke the JVM.

如果它不是在编译时完成并且它是在运行时完成的,那么为什么以下返回false(取自< a href =https://stackoverflow.com/a/513839/4801219>这个答案)?

If it is not done at compile time and it is done at runtime then why does the following return false (taken from this answer)?

// But .substring() is invoked at runtime, generating distinct objects
"test" == "!test".substring(1) // --> false

如果在运行时完成,为什么JVM不能确定它们是相同的string?

If it is done at runtime then why can't the JVM figure out that they are the same string?

我真的很困惑字符串实习如何在Java中工作以及Java字符串池的存储位置。

I am really confused as to how string interning works in Java and where exactly the Java string pool is stored.

推荐答案

编译器将文字字符串放在类文件中(并且只有唯一的字符串,它会合并所有等效的文字);加载类文件时,JVM将这些字符串加载到字符串池中。

The compiler puts the literal strings in the class file (and only unique ones, it consolidates all equivalent literals); the JVM loads those strings into the string pool when the class file is loaded.


如果在运行时完成,那么为什么不能JVM发现它们是相同的String。

If it is done at runtime then why can't the JVM figure out that they are the same String.

因为 .substring 尚未实现,因此与字符串池中的等效test字符串不同。如果您实习,您将获得 true

Because the string being returned by .substring has not been interned, and so is a different object than the equivalent "test" string in the string pool. If you interned it, you'd get true:

"test" == "!test".substring(1).intern() // true

Sections < a href =https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4> JLS的§4.4和 5.3版本的JVM规范看起来很相关。

Sections §4.4 of the JLS and §5.3 of the JVM spec look relevant.

为了清楚起见:在Java中比较字符串的正确方法是使用 .equals 方法或类似方法,而不是 == 。对字符串实例使用 == 通常不正确。 (除非你正在了解事情被拘禁的时间和方式......)

Just to be clear: The correct way to compare strings in Java is to use the .equals method or similar, not ==. Using == with string instances is usually incorrect. (Unless you're playing with understanding when and how things are interned...)

这篇关于在Java中编译时是否完成了字符串实习?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆