-2

I am learning Java basic concept recently, when I tried some code samples about String.intern there was a weird thing happened. Code below:

Snippet 1(normal):

String str1 = new String("0") + new String("0");
str1.intern();
String str2 = "00";
assertTrue(str1 == str2); // pass
assertTrue(str1.equals(str2)); // pass

Snippet 2(weird):

String str1 = new String("1") + new String("1");
str1.intern();
String str2 = "11";
assertTrue(str1 == str2); // fail; what happened???
assertTrue(str1.equals(str2)); // pass

Snippet 3(normal):

String str1 = new String("2") + new String("2");
str1.intern();
String str2 = "22";
assertTrue(str1 == str2); // pass
assertTrue(str1.equals(str2)); // pass

So, I don't understand what happened about new String("1"), it's really really confused, I need your help, Thanks a lot!

jason0x43
  • 3,363
  • 1
  • 16
  • 15
Martin
  • 35
  • 3
  • What about `assertTrue(str1.equals(str2));`? Does that pass the test? – deHaar Aug 28 '18 at 06:13
  • `assertTrue(str1.equal(str2)); // pass` – Martin Aug 28 '18 at 06:17
  • Nice... Just use `.equals()` for `String`-comparison – deHaar Aug 28 '18 at 06:18
  • Thank you, deHaar! but I wanna know why `new String("1")` failed by `==` compare reference address :( – Martin Aug 28 '18 at 06:21
  • Have a look at [this question](https://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java), the explanation and examples are great – deHaar Aug 28 '18 at 06:23
  • got it, Thank you sooo much! :) – Martin Aug 28 '18 at 06:30
  • Well @deHaar, if you read the answer of the link question, you will see that "_You almost always want to use `Objects.equals()`. In the rare situation where you know you're dealing with interned strings, you can use `==`._". And this question is clearly about testing `String.intern` which use the StringPool. So I would guess this "mistake" was done on purpose. – AxelH Aug 28 '18 at 06:34
  • @AxelH You are right, most likely, I was just not sure about it being *on purpose*, so asked about the comparison. – deHaar Aug 28 '18 at 06:38
  • @Martin, for your problem. it should be valid. "11" is added in the pool (with intern) so this statement should be correct since you get `str2` without using the constructor. What bother me is that your code can't compile. The method is `equals`, not `equal`. Is there more to the ode than this ? Not sure of what happen if your overload the pool (everything have a limit...) – AxelH Aug 28 '18 at 06:50
  • @AxelH Sorry, wrong spell. it should be `equals`. Thank you for your answer. My English is poor and I'm glad you understand my problem. In sense, when `str1 = "11"` and call the `intern` method, then assign `str2 = "11"`, `str1` and `str2` should have the same reference address, sadly they are difference, I don't know why. – Martin Aug 28 '18 at 07:05
  • @AxelH if i write code like `String str1 = (new String("1") + new String("1")).intern(); String str2 = "11"; `, `str1 == str2` are true. that's weird – Martin Aug 28 '18 at 07:07

1 Answers1

1

Any string which is already in the string literal pool will already have an object and will not be added when you call str1.intern() as it is already there.

On starting, the JVM creates thousands of objects and has many objects already in the String literal pool by the time main() is called.

Which strings are already in the pool depends on what code was run before your code.

System.out.println("Strings already in the literal pool");
for (char ch = ' '; ch < 127; ch++) {
    String s = Character.toString(ch);
    System.out.println(s + " " + (s != s.intern()));
}

prints

Strings already in the literal pool
  true
! false
" true
# false
$ false
% true
& true
' true
( false
) false
* true
+ false
, true
- true
. true
/ true
0 false
1 false
2 false
3 false
4 false
5 false
6 false
7 false
8 false
9 false
: true
; false
< true
= false
> false
? false
@ true
A false
B false
C false
D false
E false
F false
G false
H false
I true
J false
K false
L false
M false
N false
O false
P false
Q false
R false
S false
T false
U true
V false
W false
X false
Y false
Z true
[ true
\ false
] true
^ false
_ true
` false
a false
b false
c false
d false
e false
f false
g false
h false
i false
j false
k false
l false
m false
n false
o false
p false
q false
r false
s false
t false
u false
v false
w false
x false
y false
z false
{ false
| true
} false
~ false
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130