为什么不可变的 new String("fish") != new String("fish") ?
我记得读过一个章节,可能是在 Bloch 的 Effective Java 中,其中提到对于大多数情况,
String a = "fish";
String b = "fish";
大多数情况下 a == b 因为字符串是不可变的。但是由于对象的临时构造或类似的情况, new String("fish") 将产生一个不同的对象引用。
我浏览了 Bloch 关于 equals()、不变性和对象创建的章节,但找不到我记得的这一点!撕扯我的头发,有人记得在哪里描述这是为什么吗?它甚至可能不在 EJ 中,但我想找到它。提示:这在哪里解释是我的实际问题。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它与不变性无关。这是 JVM 处理字符串的方式。具有相同内容的字符串文字表示相同的对象(“字符串文字”大致意思是“用引号引起来的文本”)。 JVM 中有一个字符串对象表,每个字符串文字在该表中都只有一个对象。
但是,当您明确创建一个新实例时,您将根据从表中获取的字符串对象构造一个新的字符串对象。
对于不使用文字(而是通过调用 toString()、通过实例化等)形成的任何字符串,您可以通过调用
str.intern()
从 jvm 表中获取对象。intern()
方法为每个存在的字符序列返回一个实例。new String("fish").intern()
将返回与String s = "fish"
相同的实例有两件事要记住:
new String("something")
equals(..)
进行比较(除非您真的知道自己在做什么,并记录下来)It's not related to immutability. It's the way strings are handled by the JVM. A string literal with the same contents represents the same object ("string literal" means roughly "text surrounded by quotes"). There is a table of string objects in the JVM, and each string literal has exactly one object in that table.
However, when you expicitly create a new instance, you construct a new string object based on the string object taken from the table.
From any string formed by not using a literal (but by calling toString(), by instantiating, etc.) you can get the object from the jvm table by calling
str.intern()
. Theintern()
method returns exactly one instance for each character sequence that exists.new String("fish").intern()
will return the same instance as simplyString s = "fish"
There are two things to remember:
new String("something")
equals(..)
(unless you really know what you are doing, and document it)我认为您正在寻找 String .intern() 方法,维护常量字符串池。
运算符“==”比较对象引用(地址),而 .equals() 是一个查看语义等价性的方法调用。
编译器将查看 String a = "fish" 和 String b = "fish",然后可能会也可能不会指向相同的地址。但是,如果你执行 a.intern(); b.intern() 那么它可能会将它们放在同一个字符串池中并且 a == b。
I think you are looking for String.intern() method which maintains a constant string pool.
The operator '==' compares object references (addresses) while .equals() is a method call which looks at semantic equivalence.
The compiler will look at String a = "fish" and String b = "fish" and then may or may not point to the same address. However, if you do a.intern(); b.intern() then it will probably put them in the same string pool and a == b.
如果您正在寻找明确的描述,那么请转到定义: JLS § 3.10.5 字符串文字。
您应该熟悉的示例代码是:
If you're looking for a definitive description, well, go to the definition: JLS § 3.10.5 String Literals.
The example code you should be familiar with is,