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.

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
RohitT
  • 187
  • 2
  • 11
  • 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. – Mark Rotteveel Jul 26 '18 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. – Stephen C Jul 26 '18 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? – Andrew Tobilko Jul 26 '18 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.) – Stephen C Jul 26 '18 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. – Mark Rotteveel Jul 26 '18 at 11:31
  • @MarkRotteveel - Hi. Could you help me with the following question please. https://stackoverflow.com/questions/51753631/springmvc-property-driverclassname-threw-java-lang-illegalstateexception-cou . I am stuck and nobody has answered it. – RohitT Aug 08 '18 at 21:38

4 Answers4

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.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 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. – RohitT Jul 26 '18 at 11:26
  • 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 ? – RohitT Jul 26 '18 at 11:26
  • 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. – Stephen C Jul 26 '18 at 11:36
  • 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 ? – RohitT Jul 26 '18 at 11:43
  • 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*! – Stephen C Jul 26 '18 at 12:05
  • Hi Stephen.Thank you for the reply. 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. And there is no thing as the String constant pool in the JVM. What do you mean by that ? Could you please explain in brief. Thank you. – RohitT Jul 27 '18 at 02:35
  • *"What do you mean by that ?"* - What I mean is that there is no String constant pool. There is a String pool. It can contain String objects that were not created as literals, or declared as constants (i.e. `final`). – Stephen C Jul 27 '18 at 04:39
  • *"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 examples that you gave, it will not be true for others; e.g. `s2 = s1.substring(s1)` or `s = new String(new char[]{'J', 'a', 'v', 'a'})` – Stephen C Jul 27 '18 at 04:50
  • Thank you so much Stephen. Now all my doubts are cleared. :) – RohitT Jul 27 '18 at 13:12
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.

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
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
Mạnh Quyết Nguyễn
  • 17,677
  • 1
  • 23
  • 51
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.

Pradeep
  • 12,309
  • 3
  • 20
  • 25