Consider:
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
I got confused why they are resulting differently by the returned value of String.intern()
which says:
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
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.
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.
Updated
Thanks to the help of @Eran and @Slaw, I finally can explain what just happened there for the output
true
true
false
false
false
- Since
"Cattie & Doggie"
doesn't exist in the pool, s1.intern() will put the current object reference to the pool and return itself, so s1.intern() == s1
;
"Cattie & Doggie"
already in the pool now, so string literal "Cattie & Doggie"
will just use the reference in pool which is actually s1
, so again we have true
;
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 calling s2.intern()
, so s2.intern() != s2
and we have false
;
new String()
will also return a new instance, but when we try to s3.intern()
, it will return the previously stored reference in the pool which is actualy s1
so s3.intern() != s3
and we have false
;
- As #2 already discussed, String literal
"Cattie & Doggie"
will return the reference already stored in the pool (which is actually s1
), so s3 != "Cattie & Doggie"
and we have false
again.
Thanks for @Sunny to provide a trick to get all the interned
strings.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…