问题描述
考虑:
String s1 = new StringBuilder("Cattie").append(" & Doggie").toString();
System.out.println(s1.intern() == s1); // true why?
System.out.println(s1 == "Cattie & Doggie"); // true another why?
String s2 = new StringBuilder("ja").append("va").toString();
System.out.println(s2.intern() == s2); // false
String s3 = new String("Cattie & Doggie");
System.out.println(s3.intern() == s3); // false
System.out.println(s3 == "Cattie & Doggie"); // false
我感到困惑,为什么 String.intern()
表示:
I got confused why they are resulting differently by the returned value of String.intern()
which says:
特别是在这两项测试之后:
Especially after these two tests:
assertFalse("new String() should create a new instance", new String("jav") == "jav");
assertFalse("new StringBuilder() should create a new instance",
new StringBuilder("jav").toString() == "jav");
我曾经读过一篇文章,谈论一些在其他所有事物之前都被拘禁的特殊字符串
,但是现在这真是一个模糊.
I once read a post talking about some special strings
interned before everything else, but it's a real blur now.
如果有一些字符串是 pre-interned
,是否有一种方法可以获取它们的列表?我只是对它们的功能感到好奇.
If there are some strings pre-interned
, is there a way to get kind of a list of them? I am just curious about what they can be.
由于@Eran和@Slaw的帮助,我终于可以解释一下在那里发生的输出结果
Thanks to the help of @Eran and @Slaw, I finally can explain what just happened there for the output
true
true
false
false
false
- 由于池中不存在
"Cattie& Doggie"
,因此s1.intern()会将当前对象引用放入池中并返回自身,因此s1.intern()== s1
; -
"Cattie& Doggie"
现在已经在池中,因此字符串文字"Cattie& Doggie"
将仅使用池中的引用,而实际上是s1
,所以我们再次得到true
; -
new StringBuilder().toString()
将在池中已有"java"
时创建一个新实例,然后调用时将返回池中的引用s2.intern()
,所以s2.intern()!= s2
,我们有false
; -
new String()
也将返回一个新实例,但是当我们尝试s3.intern()
时,它将返回先前存储在池中的引用,实际上是s1
,所以s3.intern()!= s3
,我们有false
; - 正如#2所讨论的那样,字符串文字
"Cattie& Doggie"
将返回已经存储在池中的引用(实际上是s1
),因此s3!=服装和狗狗"
,我们又遇到了false
.
- Since
"Cattie & Doggie"
doesn't exist in the pool, s1.intern() will put the current object reference to the pool and return itself, sos1.intern() == s1
; "Cattie & Doggie"
already in the pool now, so string literal"Cattie & Doggie"
will just use the reference in pool which is actuallys1
, so again we havetrue
;new StringBuilder().toString()
will create a new instance while"java"
is already in the pool and then the reference in pool will be returned when callings2.intern()
, sos2.intern() != s2
and we havefalse
;new String()
will also return a new instance, but when we try tos3.intern()
, it will return the previously stored reference in the pool which is actualys1
sos3.intern() != s3
and we havefalse
;- As #2 already discussed, String literal
"Cattie & Doggie"
will return the reference already stored in the pool (which is actuallys1
), sos3 != "Cattie & Doggie"
and we havefalse
again.
感谢@Sunny提供技巧,以获取所有 interned
字符串.
Thanks for @Sunny to provide a trick to get all the interned
strings.
推荐答案
s2.intern()
仅在字符串池不存在的情况下才返回 s2
引用的实例.t在调用之前包含一个 String
,其值为"java".在执行代码之前,JDK类会内联一些 String
."java"必须是其中之一.因此, s2.intern()
返回以前的被禁实例,而不是 s2
.
s2.intern()
would return the instance referenced by s2
only if the String pool didn't contain a String
whose value is "java" prior to that call. The JDK classes intern some String
s before your code is executed. "java" must be one of them. Therefore, s2.intern()
returns the previously interned instance instead of s2
.
另一方面,JDK类没有实习任何值等于"Cattie& Doggie"的 String
,因此 s1.intern()
返回 s1
.
On the other hand, the JDK classes did not intern any String
whose value is equal to "Cattie & Doggie", so s1.intern()
returns s1
.
我不知道任何预装字符串的列表.这样的列表很可能会被视为实现细节,该细节可能因不同的JDK实现和JDK版本而异,因此不应依赖.
I am not aware of any list of pre-interned Strings. Such a list will most likely be considered an implementation detail, which may vary on different JDK implementations and JDK versions, and should not be relied on.
这篇关于返回String.intern()的说明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!