1

I was asked this question somewhere : In

String s=new String("abc");

how to programmatically prove that the String literal "abc" will be added to the String pool?

PS: I know the JLS says - All String literals(Strings enclosed between "") are added to the String pool.

Also, I looked at the Byte code generated, but in Byte code , I can see only Class Constants pool not Strings Constant pool.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • What are you saying here? `System.out.println("abc" == new String("abc"));` shows that even if the String is in the String pool the reference isn't the same. – Elliott Frisch Aug 19 '14 at 03:31
  • @ElliottFrisch - `s1.value == s2.value : true`// this proves that the internal char array is the same for both s1 snd s2 – TheLostMind Aug 19 '14 at 03:45
  • 1
    All you can prove is that if you attempt to intern the literal string you will get the same value back ... sometimes. You could try it 1000 times without proving anything, because it could fail on the 1001st attempt. – Hot Licks Aug 19 '14 at 03:51
  • @HotLicks- the identity hashcodes of both s1.value and s2.value are the same, so, internally they use the same "abc". – TheLostMind Aug 19 '14 at 03:59
  • By "programmatically prove", do you mean "demonstrate"? – Chris Martin Aug 19 '14 at 04:00
  • Can we access the string pool and see what's there? – MxLDevs Aug 19 '14 at 04:03
  • @MxyL - I don't think so. – TheLostMind Aug 19 '14 at 04:03
  • @TheLostMind -- Interning is done on the whole string object, not the internal array. It is possible, in some JVMs, to have two distinct Strings with the same internal char array, and, in fact, in older JVMs they could be two Strings with different values (yet still share the same char array). But sharing the char array does not make the two strings be the same, and is an irrelevant detail. – Hot Licks Aug 19 '14 at 14:55

1 Answers1

3

You can use

s != s.intern()

which yields true.

Explanation: Assume "abc" was not in the string pool before calling s.intern(). Then s.intern() would add s to the string pool and both sides would be equal(reference equality ==).


E.g. this prints false:

String s2 = "x".concat("yz"); // "xyz" is not in the string pool, since it's calculated using a method
System.out.println(s2 != s2.intern());

Since both sides are not equal, "abc" was in the string pool before calling intern(), which proofs the claim. (reductio ad impossibilem)


Note: This does not work, if you assign the string literal directly by using String s = "abc";. However you could still create a new string using new String(s) in that case and work with the new string.

fabian
  • 80,457
  • 12
  • 86
  • 114
  • For `String s = new String("abc")`, `s==s.intern()` returns false. Also, 'char c = {'p','q','r'};` , `String s = new String(c);` . Now if you do `s==s.intern()`, you get `false`. `pqr` is not in the String pool before intern is called. – TheLostMind Aug 19 '14 at 05:50
  • @TheLostMind: What are you trying to tell me with the first sentence??? I already have an equivalent statement in my answer (only with `!=` in place of `==` and `true` instead of `false`). The sentence "Now if you do `s==s.intern()`, you get `false`." is simply wrong (at least last time I tried it with java 8). – fabian Aug 19 '14 at 06:09