Friday, July 14, 2023

Difference between String literal and New String object in Java

The String class or java.lang.String is a special class in Java API and has so many special behaviors which are not obvious to many programmers. In order to master Java, the first step is to master the String class, and one way to explore is checking what kind of String related questions are asked on Java interviews. Apart from usual questions like why String is final or equals vs == operator, one of the most frequently asked questions is what is the difference between String literal and String object in Java

For example, what is the difference between String object created in the following two expressions:
String strObject = new String("Java");
and
String strLiteral = "Java";
Both expressions give you a String object, but there is a subtle difference between them. When you create a String object using the new() operator, it always creates a new object in heap memory

On the other hand, if you create an 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 already exists. 

Otherwise, it will create a new string object and put it in a string pool for future re-use. In the rest of this article, why it is one of the most important things you should remember about String in Java.




What is String literal and String Pool?

Since String is one of the most used types in any application, the Java designer took a step further to optimize the uses of this class. They know that Strings will not be going to be cheap, and that's why they come up with an idea to cache all String instances created inside double quotes e.g. "Java". These double quoted literal is known as String literal and the cache which stored these String instances are known as String pool

In earlier versions of Java, I think up-to Java 1.6 String pool is located in the permgen area of the heap, but in Java 1.7 updates it's moved to the main heap area. Earlier since it was in PermGen space, it was always a risk to create too many String objects, because it's very limited space, default size 64 MB, and used to store class metadata e.g. .class files. 

Also, creating too many String literals can cause java.lang.OutOfMemory: permgen space which can crash your Java application in production. 

Now because the String pool is moved to a much larger memory space, it's much safer. By the way, don't misuse memory here, always try to minimize temporary String objects e.g. "a", "b" and then "ab". Always use StringBuilder to deal with temporary String objects.

String literal vs New String in Java




Difference between String literal and String object

At a high level both are String objects, but the main difference comes from the point that the new() operator always creates a new String object. Also when you create String using literal they are interned. This will be much more clear when you compare two String objects created using String literal and new operator, as shown in the below example :

String a = "Java";
String b = "Java";
System.out.println(a == b);  // True

Here two different objects are created and they have different references:

String c = new String("Java");
String d = new String("Java");
System.out.println(c == d);  // False

Similarly, when you compare a string literal with a String object created using new() operator using == operator, it will return false, as shown below :

String e = "JDK";
String f =  new String("JDK");
System.out.println(e == f);  // False

In general, you should use the string literal notation when possible. It is easier to read and it gives the compiler a chance to optimize your code. By the way, any answer to this question is incomplete until you explain what is String interning, so let's see that in the next section.

String interning using inter() method

Java by default doesn't put all String objects into the String pool, instead, it gives you the flexibility to explicitly store any arbitrary object in the String pool. You can put any object to the String pool by calling the intern() method of java.lang.String class. Though, when you create using String literal notation of Java, it automatically calls intern() method to put that object into String pool, provided it was not present in the pool already. 

This is another difference between string literal and new string because in case of new, interning doesn't happen automatically until you call the intern() method on that object. Also, don't forget to use StringBuffer and StringBuilder for string concatenation, they will reduce the number


That's all about this question, what is the difference between String literal and String objects in Java. Always remember that literal Strings are returned from the string pool and Java put them in the pool if not stored already. This difference is most obvious when you compare two String objects using equality operator (==). 

That's why it's suggested to always compare two String objects using the equals() method and never compare them using the == operator, because you never know which one is coming from pool and which one is created using new() operator. 

If you know the difference between string object and string literal, you can also solve questions from Java written test, which also test this concept. It's something, every Java programmer should know.  of temporary String object in heap space.

51 comments:

  1. Thank you for this question I was very confuse about this string literal and string object but your tutorial give me clear idea about that thank you once again.....

    ReplyDelete
  2. Thanks for your article. Could you please tell me. How many objects are created in memory and at which place? when we create objects using new keyword?

    ReplyDelete
    Replies
    1. Good question. For example if you execute following two lines :

      String language = "Java";
      String anotherLanguage = new String("Java")

      how many objects are created in where i.e. heap, stack and pool?

      In first statement one String is created using literal syntax so that will go to the String pool, which is also part of heap from Java 1.7 but was part of permgen area in Java 1.6. In second statement, "Java" will not create another object instead it will reuse the object created in previous step, had it been any other word e.g. "java" it would have created another object. By the way new String() will create another object in Java heap space. No object in stack but reference variables language and anotherLanugage will be created and stored in stack.

      Delete
    2. I'm a little bit confused about the second statement in the expressions above executed:

      String language = "Java";
      String anotherLanguage = new String("Java");

      After the execution of first statement, the String Literal "Java" is created in String Pool.But then in second statement, I think that the "Java" will be created in Heap area, although I may be wrong in this but to the point I know I think that's the way it is. Although I'm not confirm about where the "Java"in the second statement parenthesis will be created/or not.

      Can anyone please clarify/

      Delete
    3. This is how 2nd statement works
      1) Scan SCP . if it has already same string then return old one, else create new object in SCP.
      2) Create one String object in Heap(due to new)

      Totally 2 objects in general.

      Delete
    4. Don't think so, Only one object will be created .If we call intern then the object should be created in String pool.

      Delete
    5. new String("..") always creates an object in heap we all know
      but the question is ,is it also check in String pool.???

      Delete
    6. No. In that case it wouldn't create object on the Heap exclusively.

      Delete
  3. I think main difference between String object and String literal still remains the fact that former is automatically added into String pool while later is added using intern() method.

    ReplyDelete
  4. I have a question, can a String Constant Pool be Garbage Collected. If so when & how?

    ReplyDelete
    Replies
    1. Yes, both interned String and literals are subject to garbage collection. when a String literl doesn't have any active reference it becomes eligible for garbage collection and this is true for all Java versions. In Java 7, String pool is moved to heap space, but even when it was in PermGen space untile Java 6, String constants were garbage collected.

      Delete
  5. very good explanation of the String objects & their differences. Thanks a lot.

    ReplyDelete
  6. I am still confused about how many objects created when u create string using new operator.
    as per me if I write String s = new String("ABC") then two objects are created
    one in heap and one in String pool.
    Please provide your feedback.

    ReplyDelete
    Replies
    1. @Anonymous, that is correct, two objects, "ABC" on String pool and new String() on heap.

      Delete
    2. Nope, until you explicitly call intern() method, it will create one object in Heap space only.

      Delete
  7. When executing String s = new String("ABC") , only one object is created in the heap. This doesn't not deal with String pool.

    ReplyDelete
    Replies
    1. Actually two objects are created, first the "ABC" object which is created in String pool and second the new String() object which is created in heap. String pool is also now part of Java heap from JDK 7 release update 40 I guess.

      Delete
    2. SO in this case how intern() method is used? and what is the advantage of having intern() method if string is already in pool even using with new operator

      Delete
    3. yes Sridhar , me too having same point can anyone please clear me.

      Delete
  8. String str = "ABC" + "DEF"; How many object will be created in this.

    ReplyDelete
    Replies
    1. Hi @Davinder, four objects will be created

      1) "ABC"
      2) "DEF"
      3) The StringBuilder object which will used for concatenation
      4) The String object which will be created after concatenation e.g. "ABCDEF"

      Java internally uses StringBuilder or StringBuffer when you use + operator to join string together.

      Delete
  9. Hi.
    What is the use of creating two object i.e using new keyword .
    For Ex. String S=new String("abc");
    In this example there will be 2 objects. 1 in string Pool and 1 in NonPool Memory.
    But what is the relevance of String pool object when using new Keyword. Is it available for next time when we create another object using new keyword with same value and if not then why it is there?

    ReplyDelete
    Replies
    1. hello @Himanshu, it will be returned when you create another object using same character but by using String literal e.g. "abc" will return the same object.

      Delete
  10. The same question...
    Are 2 objects created ?

    String s=new String("abc");

    Or only 1 object in non-pool heap memory is created?

    ReplyDelete
    Replies
    1. Hello Aditya, Yes, two objects are created if "abc" is not in the String pool already, if it is then just one. First object is "abc" and second is the new String().

      Yes, only "abc" will be created in pool, s will not go to pool until you call s.intern()

      Delete
    2. there will be two objects created s will be in heap and by "abc" literal object will be go in the string constant pool.
      if there is already a "abc" present than it will not create new and give the reference of previous "abc".
      Take A example:
      class intern
      {
      public static void main(String... s)
      {
      String s6 = "arpan";
      String s5 = "arpan";
      if(s5==s6)
      System.out.println("true");
      }}

      Delete
  11. is it possible to put a string only in heap memory not in string constant pool.

    ReplyDelete
    Replies
    1. @true taller yes, if you create an object using new String() without using String literal e.g. via byte array then that object only remain in heap space, not created in String pool.

      Delete
  12. Can you tell me how many objects created here

    String ab="ab"+"ba";
    String ba="ba"+"ab";

    ReplyDelete
    Replies
    1. @Anonymous, 4 objects, two String literal and two created by String concatenation.

      Delete
  13. String s="abc";
    if(s=="abc")
    {
    System.out.print("true");
    }

    Does the result will be true in this casse?

    ReplyDelete
    Replies
    1. @Anonymous, yes result will be true because both are pointing to same String literal.

      Delete
  14. when you say if we call itern() on string object it moves to string constant pool.

    System.out.println("Testing intern");
    String test = "intern";
    String test1 = new String("intern");
    System.out.println(test == test1);// it will return false no doubt about it
    test1.intern();// moved string object into pool having same literal
    System.out.println(test == test1); // it should have written true but its not

    ReplyDelete
    Replies
    1. Hello @Anonymous, the intern() method has no effect on existing object. Now, if you create another object with literal e.g. "intern" then same object is returned instead of creating a new one. See my post when to use intern() method of String in Java to learn more about intern

      Delete
  15. String a = "one";
    String b = "two";
    String c = a+b;
    String d = "one"+"two";
    String e = "onetwo";
    if(c==d){
    System.out.println(true);//1st
    }else if(c==e){
    System.out.println(true);//2nd
    }else if(d==e){
    System.out.println(true);//3rd
    }else{
    System.out.println(true);//4th
    }


    Explain Mr. Javin Paul,
    1.Why 3rd will be true and why not 1/2?
    2. Afetr concatenation will new object will be created in heap/pool?

    ReplyDelete
  16. Very good explanation, thank you!

    But this is an exception, a trick and any exception makes our life harder and it pales the beauty of Java.
    Why Java designers did not automatically decide if a string in PermGen to use it no matter it is literal or new object?
    So if after a
    String s1="Java";
    //coming with
    String s2 = new String("Java");
    to return also s1 as it is already there?

    This in idea that Java is a tool in our hands not vice-verse.
    And we prefer simple but effective tools.

    ReplyDelete
  17. why they need it
    why they create two different type String object..
    in case of String str=new String("Hello");
    two String object is created...why it need...

    ReplyDelete
  18. String a="a";
    String b="b";
    String c=a+b+"c";
    String d=new String ();

    How many string objects are created in this code?

    ReplyDelete
  19. String j = "Java";
    String f = new String("Java");

    System.out.println(j.equals(f));
    System.out.println(j==f);

    ReplyDelete
    Replies
    1. why both false, first should be true, second should be false as first will do content matching while second will check if both are same object using memory reference.

      Delete
  20. String j = "Java";
    String f = new String("Java");

    System.out.println(j.equals(f)); // true
    System.out.println(j==f); // false Why? If f doesn't create a new object and uses reference of j. Then why false?

    ReplyDelete
    Replies
    1. Please read the article, they are different object and == only return true for same object, not same content of different object, which equals does.

      Delete
  21. I think there are false sentences in the article. Or I may have misunderstood me. When I search on the internet, when I say new String ("abc"), 2 values are created in memory, including a heap and a String pool. I agree that there is no value in the pool.
    Then the following sentences in the article attract my attention. And I can not understand. It says that it will not be put in the pool without calling the intern () method. Do I get it wrong?

    "Java by default doesn't put all String object into String pool, instead they gives you flexibility to explicitly store any arbitrary object in String pool. You can put any object to String pool by calling intern() method of java.lang.String class."

    According to these sentences, when I say new String ("abc"), if I don't call the intern () method, it will not be put in the pool. However, it does not write like this on the Internet.Can you explain it to me?

    ReplyDelete
  22. Hello OMER,
    When you write String str = new String ("abc") there are two objects created here, string literal "abc" which is created in String pool and an object refereed by str, both contains "abc" but one is in heap and other is in string pool. if you do str.intern() then it will refer to same object as "abc". You can try it yourself by comparing using == operator to find out more.

    ReplyDelete
  23. Hello Javin,

    So, string literal "abc" is now eligible for garbage collection if we do not use inter() explicitly as no reference to it by str. Correct me if I'm going in a wrong directions please.

    ReplyDelete
    Replies
    1. Yes, heap object is eligible to garbage collection if there is no reference, object inside pools are not, but thankfully string pool from java7 is migrated to heap which means they can be garbage collected.

      Delete

Feel free to comment, ask questions if you have any doubt.