0

I attended interview and i was asked this question.

String s=new String("Rohit"); 

Does this statement creates an object in heap only or it makes an entry in string pool as well?

I answered it does not make entry in pool. I think with .intern() it would make entry in string pool. Interviewer's thought was opposite.

Could you please guide me if i was wrong or interviewer?

Thanks in Advance.

EDIT:

String s1=new String("Rohit");

        String s2="Rohit";

        String s3=new String("Rohit").intern();

        System.out.println(" "+(s2==s3)+" "+(s1==s2)+" "+(s1==s3)+" "+(s2==s3));

results as :true false false true

This makes me to think that without using intern() with new, there is no entry in pool for this object

Rajesh
  • 213
  • 4
  • 15
  • For quick answer any string literal such as "Rohit" in this case will go into string constant pool and string `s` will go into heap that will point the string stored in string constant pool. – Braj Jul 26 '14 at 12:44
  • The "entry in string pool" (a improper description of interning) is created when the class is loaded and the string literal "Rohit" is resolved in the class's constant pool. Executing the `new String` operation does not create a new interned string (or cause the existing one to be shared). – Hot Licks Jul 26 '14 at 12:45
  • @Braj - But that statement does not "create" the interned string. Rather, loading the class does that (assuming that "Rohit" wasn't already interned by some other class). – Hot Licks Jul 26 '14 at 12:47
  • And `s` will not point to the interned string -- it will be its own object. – Hot Licks Jul 26 '14 at 12:48
  • @HotLicks I have reopened it. Now you are free to answer it. – Braj Jul 26 '14 at 12:51
  • read this [post](http://stackoverflow.com/questions/23544752/difference-among-several-ways-of-creating-string/23544859#23544859) that might help you. – Braj Jul 26 '14 at 12:52
  • 1
    When talking about objects, remember that String is *two objects* one of them a `char[]`. – Peter Lawrey Jul 26 '14 at 14:12
  • @PeterLawrey Could you please point out my mistake in understanding it, as per the EDIT in question. Please... I still make mess of it – Rajesh Jul 26 '14 at 14:21
  • @Rajesh I have added an answer though it is just an update patch to HotLick's answer as it is unreadable as a comment. – Peter Lawrey Jul 26 '14 at 14:33

2 Answers2

4

Several things wrong with what you say he said:

First, doing new String always returns a new string, and never one that is interned.

Second, while it is true that the presence of the string literal "Rohit" might cause a String of that value to be "interned" (what is erroneously referred to as placing in the "string pool" or "string constant pool"), that would be done (if it was done) when the class was loaded, not when the statement was executed.

Third, since there can only ever be one copy of a String with a given pattern in the interned string table, even loading the class is not guaranteed to add a new entry, since one might already be there.

Of course, as is often the case, there may have been some misunderstanding on the part of one or both of you, or the question (or your answer) may have been poorly/unclearly worded.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
  • +1 `new` means new object, always. If there is no `new` there isn't a new object. – Peter Lawrey Jul 26 '14 at 14:08
  • In Java 7+ the literal is interned when the statement is executed (for a String which hasn't been interned before) AFAIK. I had a test which showed this was different to Java 6, I can't remember what it was now. – Peter Lawrey Jul 26 '14 at 14:11
  • @PeterLawrey Actually From String s1=new String("Rohit"); String s2="Rohit"; String s3=new String("Rohit").intern(); System.out.println(" "+(s2==s3)+" "+(s1==s2)+" "+(s1==s3)+" "+(s2==s3));--->true false false true I infer that with new only when intern() is used, there is an entry in pool. – Rajesh Jul 26 '14 at 14:17
  • @Rajesh Found it. String.intern() will return the same object if it is not in the string pool already. It will return another String if it is already loaded. `StringBuilder sb = new StringBuilder("Hell"); sb.append("o"); String s = sb.toString(); String si = s.intern(); /* same string if not loaded. */ String s2 = "Hello"; System.out.println( System.getProperty("java.version")+" " + (s == si) + " "+(s2 == s));` prints `1.6.0_45 false false` as you expect, but `1.7.0_45 true true` – Peter Lawrey Jul 26 '14 at 14:25
0

I agree with @Hot Licks, but the behaviour of when a String literal is loaded changed in Java 7 AFAICS.

String literals are loaded when the class is loaded in Java 6 but in Java 7 they changed this to be when the first line which uses the string is executed. You can detect this by looking at the String returned by String.intern(); The first time it is called for a String it will return the same object, however when called again with an equals() String it will return the previous object.

StringBuilder sb = new StringBuilder("Hell");
sb.append("o");
String s = sb.toString();
String si = s.intern(); /* same string if not loaded. */
String s2 = "Hello";
System.out.println( System.getProperty("java.version")+" " + (s == si) + " "+(s2 == s)); 

prints

1.6.0_45 false false

as you expect, but in Java 7+

1.7.0_45 true true 

If s2 is loaded first, the intern() string si will be the same as it, and thus different to s However, if s2 is loaded after, all the Strings use the same object.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Of course, there is no guarantee that `intern` will return the same string, even if it is the very first time that character sequence was interned. `intern` is at liberty to return a new instance instead. – Hot Licks Jul 26 '14 at 17:54
  • @HotLicks The Javadoc for Java 7 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." – Peter Lawrey Jul 26 '14 at 18:06