4
  1. Say if there are no strings in the String constant pool, and if I say,

    String s = "Java";
    

    Then how many objects will be created?

  2. Now again nothing in the pool, and I say,

    String s = new String("Java");
    

    Now, how many objects will be created?

  3. Now again nothing in the pool, and I say,

    String s = new String("Java");
    s.intern();
    

    What will the intern method do?

  4. Now again nothing in the pool, and I say,

    String s = new String("Java");
    String s1 = s.intern();
    

    What will happen now?

Please answer as I am really confused about it.

As I read in SCJP5 Kathy Sierra book, that when you create a String with new, then 2 objects are created, one on the heap and one in the pool.

6
  • 1
    In normal usage of Java you should hardly ever care about string interning, nor should your code ever contain String.intern() (as with all rules, there are exceptions, but really don't use it unless you have an extremely good reason for it). Don't get hung up on stuff like this, it is really unimportant when learning to program Java. Commented Jul 26, 2018 at 11:17
  • Agreed. Unfortunately, SCJP exams ask stupid questions that require knowledge like this. Even more unfortunately, the questions are often asked in an ambiguous way ... and as a result there is no single correct answer. Commented Jul 26, 2018 at 11:23
  • @MarkRotteveel, I would like to reopen the question because it's more detailed and more practically useful than the pinned one, don't you think so? Commented Jul 26, 2018 at 11:25
  • 1
    @AndrewTobilko - I think it should stay closed. No more answers are needed. Seriously. Yes, the details are different, yes answering was useful for the OP, but the information is all in the original Q&A. (You could say, this one is just an illustration for the original.) Commented Jul 26, 2018 at 11:28
  • 1
    @AndrewTobilko The duplicate I selected asks the same question, it just does it without breaking it up in separate steps. The answer there also fully explains it. I don't see a good reason to reopen. Commented Jul 26, 2018 at 11:31

4 Answers 4

4

I will assume that in each example below you load and execute the code exactly once, in a new JVM each time. (I will also assume that nowhere else in your code do you use the literal "Java" ... since that would complicate things.)


1) Say if there are no strings in the String constant pool, and if i say,

String s = "Java";

Then how many objects will be created ?

One string is created and added to the pool when method is loaded.


2) Now again nothing in the pool, and i say,

String s = new String("Java");

Now how many objects will be created.

One string is created and added to the pool when method is loaded.

A second string is created by the new when the code is run, and it is NOT added to the pool.


3) Now again nothing in the pool, and i say,

String s = new String("Java");
s.intern();

What will the intern method do ?

One string is created and added to the pool when method is loaded.

A second string is created by the new, and it is NOT added to the pool.

The intern call returns the first string. (You don't keep the reference ...)


4) Now again nothing in the pool, and i say,

String s = new String("Java");
String s1 = s.intern();

What will happen now?

Same as example 3. Thus, s1 will hold a reference to the String object that represents the "Java" string literal.


I read in SCJP5 Kathy Sierra book, that when you create a String with new, then 2 objects are created, one on the heap and one in the pool.

I doubt that the book said that exactly. (You are paraphrasing, and I think you have paraphrased somewhat inaccurately.)

However, your paraphrasing is roughly correct, though (an this is important!) the string object representing the literal is created and added to the pool when the code fragment is loaded1, not when it is executed.


And to address another point of confusion:

"What i actually meant was that from the answer that you gave, it seems that a String will always be added in the String constant pool."

That is incorrect. It is a false generalization.

While it is true for all 4 of the cases above, it will not be true for others. It depends on where the original string came from. In typical applications, most text data is read from a file, socket, or a user interface. When that happens, the strings are created from arrays of characters, either directly or via a library call.

Here is a simple (but unrealistic) example that shows creating a String from its component characters.

String s = new String(new char[]{'J', 'a', 'v', 'a'});

In the snippet above, only one String is created, and it is NOT in the String pool. If you wanted the resulting string to be in the string pool you need to explicitly call intern something like this:

String s = new String(new char[]{'J', 'a', 'v', 'a'});
s = s.intern();

... which will (if necessary) create a second string in the string pool2.


1 - Apparently, in some JVMs creation and interning string literals is done lazily, so it is not possible to say with 100% certainty when it actually happens. However, it will only occur once (per class that references the literal), no matter how many times the code fragment is executed by the JVM.

2 - There is no way to new a string into the string pool. It would actually be a violation of the JLS. The new operation is specified by the JLS as always creating a new object.

Sign up to request clarification or add additional context in comments.

9 Comments

Hi Stephen, Thank you for the answer. All the cases are separate from each other. From what i understood. In 1st case, "Java" object will be created in the pool and s will point to it. In the 2nd case, "Java" object will be created in the heap as well as the pool. So 2 objects are created. And s will point to the object in the heap and for the object in the pool there will be no reference. For the 3rd case, again 2 objects will be created. Then intern method will try to put "Java" object in the pool, but it will already be there. So intern wont do much of anything as such.
Now in the 4th case, 2 objects will be created. intern wont be of any help here as well. s1 will point to the object in the pool and s to the object in the heap. Am i correct ?
Yes. The intern() is equally useless in the 3rd & 4th cases. And the new is useless in all cases too! These examples are nothing to do with usefulness. They are about understanding the gory details of the workings of the string pool and interning. But in reality, there is just one thing you need to know for 99.9% of practical programs: don't use == to test string equality.
Thank you Stephen for the clarification. I checked the answer to the question you had marked as duplicate, there it states, "Note that you can call intern() on a String object. This will put the String object in the pool if it is not already there, and return the reference to the pooled string." From what i know, whenever i create a String, be it a literal or new, then it will always put it in the String constant pool. "This will put the String object in the pool if it is not already there". But it will always be in the pool. So whats the point of the intern method ?
What is stated in the dup Q&A is correct. "From what i know, whenever i create a String, be it a literal or new, then it will always put it in the String constant pool." - THAT is incorrect. Indeed, my answer to this Question is saying that that statement is incorrect as well. The result of new is NOT put into the string pool. (And there is no such thing as the "string constant pool" ... in the JVM.) We are not going to be able to "clear your doubt" if you disbelieve our answers or don't read them carefully!
|
3
  1. Then how many objects will be created?

There is one String in the pool.

  1. Now how many objects will be created?

One String will be created, there is still one String in the pool.

  1. What will the intern method do?

It will try to put a "Java" into the pool, find another "Java" there, are return a reference to that "Java" from step 1.

  1. What will happen now?

The "Java" from step 1 will come back and s1 now refers to it.

3 Comments

Hi Andrew, thanks for the prompt answer. But my doubt is not cleared yet.
@RohitT, throw your questions, mate. We will find answers for them.
@RohitT: So what is your doubt?
0
  1. Say if there are no strings in the String constant pool, and if i say,

    String s = "Java";

Then how many objects will be created ?

One String object is created in intern pool. s is assigned by that reference.

  1. Now again nothing in the pool, and i say,

    String s = new String("Java"); Now how many objects will be created. Two String object is created.

One is interned "Java", and one is new String with the same content of "Java"

  1. Now again nothing in the pool, and i say,

    String s = new String("Java"); s.intern(); What will the intern method do ?

The intern() method will:

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.

So in this case, this String is added to the pool and a reference to this is returned

And the last question:

  1. Now again nothing in the pool, and i say,

    String s = new String("Java"); String s1 = s.intern(); What will happen now?

What happen here is:

  1. String "Java" is added to the pool
  2. New String is created, backed by the same char[] array "Java"
  3. s.intern() look for a reference in the pool and s1 is assigned by the interned reference

Comments

0
String strObject = new String("Java");

and

String strLiteral = "Java";

Both expression gives you String object, but there is subtle difference between them.
When you create String object using new() operator, it always create a new object in heap memory.

On the other hand, if you create object using String literal syntax e.g. "Java", it may return an existing object from String pool (a cache of String object in Perm gen space, which is now moved to heap space in recent Java release), if it's already exists. Otherwise it will create a new string object and put in string pool for future re-use.

  1. String s = "Java";

One object will be created in Pool.

  1. Now again nothing in the pool, and i say,

String s = new String("Java");

One Object will be created in Heap

  1. Now again nothing in the pool, and i say,

String s = new String("Java");
s.intern();

What will the intern method do ?
intern() method will copy the Sting object into pool, but it will be no use, as it is not referenced, hence there will be only object in Heap

  1. Now again nothing in the pool, and i say,

String s = new String("Java");
String s1 = s.intern();

What will happen now?

one object in Heap and one object in Pool will be created.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.