What is the difference between “text” and new String(“text”)?












161














What is the difference between these two following statements?



String s = "text";

String s = new String("text");









share|improve this question
























  • Related topic: JEP 192: String Deduplication in G1.
    – Basil Bourque
    Jun 7 at 22:49


















161














What is the difference between these two following statements?



String s = "text";

String s = new String("text");









share|improve this question
























  • Related topic: JEP 192: String Deduplication in G1.
    – Basil Bourque
    Jun 7 at 22:49
















161












161








161


87





What is the difference between these two following statements?



String s = "text";

String s = new String("text");









share|improve this question















What is the difference between these two following statements?



String s = "text";

String s = new String("text");






java string






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 25 '15 at 22:13









nbro

5,52984793




5,52984793










asked Jun 16 '10 at 10:29









user368141

811275




811275












  • Related topic: JEP 192: String Deduplication in G1.
    – Basil Bourque
    Jun 7 at 22:49




















  • Related topic: JEP 192: String Deduplication in G1.
    – Basil Bourque
    Jun 7 at 22:49


















Related topic: JEP 192: String Deduplication in G1.
– Basil Bourque
Jun 7 at 22:49






Related topic: JEP 192: String Deduplication in G1.
– Basil Bourque
Jun 7 at 22:49














9 Answers
9






active

oldest

votes


















163














new String("text");
explicitly creates a new and referentially distinct instance of a String object; String s = "text"; may reuse an instance from the string constant pool if one is available.



You very rarely would ever want to use the new String(anotherString) constructor. From the API:




String(String original) : Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since strings are immutable.




Related questions




  • Java Strings: “String s = new String(”silly“);”

  • Strings are objects in Java, so why don’t we use ‘new’ to create them?




What referential distinction means



Examine the following snippet:



    String s1 = "foobar";
String s2 = "foobar";

System.out.println(s1 == s2); // true

s2 = new String("foobar");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true


== on two reference types is a reference identity comparison. Two objects that are equals are not necessarily ==. It is usually wrong to use == on reference types; most of the time equals need to be used instead.



Nonetheless, if for whatever reason you need to create two equals but not == string, you can use the new String(anotherString) constructor. It needs to be said again, however, that this is very peculiar, and is rarely the intention.



References




  • JLS 15.21.3 Reference Equality Operators == and !=


  • class Object - boolean Object(equals)


Related issues




  • Java String.equals versus ==

  • How do I compare strings in Java?






share|improve this answer



















  • 3




    If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
    – Kaveesh Kanwal
    Apr 16 '15 at 18:34










  • Why nobody answer preceding question?
    – zeds
    Dec 1 '15 at 5:56






  • 2




    @KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2 "abc"s. Only one of them will go to the String pool, and the other one will refer to it. Then there's the s which will be proper new object.
    – Kayaman
    Mar 16 '16 at 11:21






  • 1




    @Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
    – user968813
    May 3 '16 at 7:38












  • There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
    – user207421
    Apr 24 at 11:45





















99














String literals will go into String Constant Pool.



The below snapshot might help you to understand it visually to remember it for longer time.



enter image description here





Object creation line by line:



String str1 = new String("java5");


Using string literal "java5" in the constructor, a new string value is stored in string constant pool.
Using new operator, a new string object is created in the heap with "java5" as value.



String str2 = "java5"


Reference "str2" is pointed to already stored value in string constant pool



String str3 = new String(str2);


A new string object is created in the heap with the same value as reference by "str2"



String str4 = "java5";


Reference "str4" is pointed to already stored value in string constant pool



Total objects : Heap - 2, Pool - 1



Further reading on Oracle community






share|improve this answer



















  • 1




    Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
    – CoronaPintu
    May 12 '14 at 8:25






  • 2




    yes i had check it will not change the value of str4
    – CoronaPintu
    May 12 '14 at 8:33










  • @Braj Can you provide documentation of your Answer’s assertion?
    – Basil Bourque
    Jul 1 '15 at 16:47










  • @Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
    – Rahul Kurup
    Aug 8 '15 at 10:52










  • Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
    – user207421
    Feb 7 '16 at 9:31



















15














One creates a String in the String Constant Pool



String s = "text";


the other one creates a string in the constant pool ("text") and another string in normal heap space (s). Both strings will have the same value, that of "text".



String s = new String("text");


s is then lost (eligible for GC) if later unused.



String literals on the other hand are reused. If you use "text" in multiple places of your class it will in fact be one and only one String (i.e. multiple references to the same string in the pool).






share|improve this answer























  • Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
    – user207421
    Jun 16 '10 at 10:38












  • @EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
    – user159088
    Jun 16 '10 at 10:43



















8














JLS



The concept is called "interning" by the JLS.



Relevant passage from JLS 7 3.10.5:




Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.



Example 3.10.5-1. String Literals



The program consisting of the compilation unit (§7.3):



package testPackage;
class Test {
public static void main(String args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }


and the compilation unit:



package other;
public class Other { public static String hello = "Hello"; }


produces the output:



true true true true false true



JVMS



JVMS 7 5.1 says:




A string literal is a reference to an instance of class String, and is derived from a CONSTANT_String_info structure (§4.4.3) in the binary representation of a class or interface. The CONSTANT_String_info structure gives the sequence of Unicode code points constituting the string literal.



The Java programming language requires that identical string literals (that is, literals that contain the same sequence of code points) must refer to the same instance of class String (JLS §3.10.5). In addition, if the method String.intern is called on any string, the result is a reference to the same class instance that would be returned if that string appeared as a literal. Thus, the following expression must have the value true:



("a" + "b" + "c").intern() == "abc"


To derive a string literal, the Java Virtual Machine examines the sequence of code points given by the CONSTANT_String_info structure.




  • If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String.


  • Otherwise, a new instance of class String is created containing the sequence of Unicode code points given by the CONSTANT_String_info structure; a reference to that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.





Bytecode



It is also instructive to look at the bytecode implementation on OpenJDK 7.



If we decompile:



public class StringPool {
public static void main(String args) {
String a = "abc";
String b = "abc";
String c = new String("abc");
System.out.println(a);
System.out.println(b);
System.out.println(a == c);
}
}


we have on the constant pool:



#2 = String             #32   // abc
[...]
#32 = Utf8 abc


and main:



 0: ldc           #2          // String abc
2: astore_1
3: ldc #2 // String abc
5: astore_2
6: new #3 // class java/lang/String
9: dup
10: ldc #2 // String abc
12: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
15: astore_3
16: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_1
20: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
26: aload_2
27: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
30: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
33: aload_1
34: aload_3
35: if_acmpne 42
38: iconst_1
39: goto 43
42: iconst_0
43: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V


Note how:





  • 0 and 3: the same ldc #2 constant is loaded (the literals)


  • 12: a new string instance is created (with #2 as argument)


  • 35: a and c are compared as regular objects with if_acmpne


The representation of constant strings is quite magic on the bytecode:




  • it has a dedicated CONSTANT_String_info structure, unlike regular objects (e.g. new String)

  • the struct points to a CONSTANT_Utf8_info Structure that contains the data. That is the only necessary data to represent the string.


and the JVMS quote above seems to say that whenever the Utf8 pointed to is the same, then identical instances are loaded by ldc.



I have done similar tests for fields, and:





  • static final String s = "abc" points to the constant table through the ConstantValue Attribute

  • non-final fields don't have that attribute, but can still be initialized with ldc


Conclusion: there is direct bytecode support for the string pool, and the memory representation is efficient.



Bonus: compare that to the Integer pool, which does not have direct bytecode support (i.e. no CONSTANT_String_info analogue).






share|improve this answer































    1














    Think of "bla" being a magic factory like Strings.createString("bla") (pseudo). The factory holds a pool of all strings yet created this way.



    If it gets invoked, it checks if there is already string in the pool with this value. If true, it returns this string object, hence to strings obtained this way are indeed the same object.



    If not, it creates a new string object internally, saves it in the pool and then returns it. Thus, when the same string value is queried the next time, it returns the same instance.



    Manually creating new String("") overrides this behaviour by bypassing the string literal pool. So equality should always be checked using equals() which compares the character sequence instead of the object reference equality.






    share|improve this answer





















    • The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
      – user207421
      Feb 7 '16 at 9:20





















    1














    One simple way to understand the difference is below:-



    String s ="abc";
    String s1= "abc";
    String s2=new String("abc");

    if(s==s1){
    System.out.println("s==s1 is true");
    }else{
    System.out.println("s==s1 is false");
    }
    if(s==s2){
    System.out.println("s==s2 is true");
    }else{
    System.out.println("s==s2 is false");
    }


    output is



    s==s1 is true
    s==s2 is false


    Thus new String() will always create a new instance.






    share|improve this answer





























      1














      @Braj : i think u have mentioned the other way around. Please correct me if i am wrong



      Object creation line by line:



      String str1 = new String("java5")



         Pool- "java5" (1 Object)

      Heap - str1 => "java5" (1 Object)


      String str2 = "java5"



        pool- str2 => "java5" (1 Object)

      heap - str1 => "java5" (1 Object)


      String str3 = new String(str2)



        pool- str2 => "java5" (1 Object)

      heap- str1 => "java5", str3 => "java5" (2 Objects)


      String str4 = "java5"



        pool - str2 => str4 => "java5" (1 Object)

      heap - str1 => "java5", str3 => "java5" (2 Objects)





      share|improve this answer





















      • str1 is not involved in the value of str2 or str3 or str4 in any way.
        – user207421
        Feb 7 '16 at 9:24



















      0














      Although it looks the same from a programmers point of view, it has big performance impact. You would want to use the first form almost always.






      share|improve this answer





























        0














        String str = new String("hello")


        It will check whether String constant pool already contains String "hello"?
        If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.



        An object will be created in a heap memory area and str reference points to object created in heap memory location.



        if you want str reference to point object containing in String constant pool then one has to explicitly call str.intern();



        String str = "world";


        It will check whether String constant pool already contains String "hello"?
        If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.



        In both the above case, str reference points to String "world" present in Constant pool.






        share|improve this answer





















        • 'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
          – user207421
          Feb 7 '16 at 9:28










        • Can you please explain what is wrong in this post clearly?
          – Jayesh
          Feb 7 '16 at 9:46










        • What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
          – user207421
          Oct 22 '16 at 7:22










        • @EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
          – Jayesh
          Oct 22 '16 at 7:43










        • You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
          – user207421
          Aug 23 '17 at 4:02












        protected by ΦXocę 웃 Пepeúpa ツ Sep 8 '17 at 5:49



        Thank you for your interest in this question.
        Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



        Would you like to answer one of these unanswered questions instead?














        9 Answers
        9






        active

        oldest

        votes








        9 Answers
        9






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        163














        new String("text");
        explicitly creates a new and referentially distinct instance of a String object; String s = "text"; may reuse an instance from the string constant pool if one is available.



        You very rarely would ever want to use the new String(anotherString) constructor. From the API:




        String(String original) : Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since strings are immutable.




        Related questions




        • Java Strings: “String s = new String(”silly“);”

        • Strings are objects in Java, so why don’t we use ‘new’ to create them?




        What referential distinction means



        Examine the following snippet:



            String s1 = "foobar";
        String s2 = "foobar";

        System.out.println(s1 == s2); // true

        s2 = new String("foobar");
        System.out.println(s1 == s2); // false
        System.out.println(s1.equals(s2)); // true


        == on two reference types is a reference identity comparison. Two objects that are equals are not necessarily ==. It is usually wrong to use == on reference types; most of the time equals need to be used instead.



        Nonetheless, if for whatever reason you need to create two equals but not == string, you can use the new String(anotherString) constructor. It needs to be said again, however, that this is very peculiar, and is rarely the intention.



        References




        • JLS 15.21.3 Reference Equality Operators == and !=


        • class Object - boolean Object(equals)


        Related issues




        • Java String.equals versus ==

        • How do I compare strings in Java?






        share|improve this answer



















        • 3




          If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
          – Kaveesh Kanwal
          Apr 16 '15 at 18:34










        • Why nobody answer preceding question?
          – zeds
          Dec 1 '15 at 5:56






        • 2




          @KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2 "abc"s. Only one of them will go to the String pool, and the other one will refer to it. Then there's the s which will be proper new object.
          – Kayaman
          Mar 16 '16 at 11:21






        • 1




          @Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
          – user968813
          May 3 '16 at 7:38












        • There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
          – user207421
          Apr 24 at 11:45


















        163














        new String("text");
        explicitly creates a new and referentially distinct instance of a String object; String s = "text"; may reuse an instance from the string constant pool if one is available.



        You very rarely would ever want to use the new String(anotherString) constructor. From the API:




        String(String original) : Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since strings are immutable.




        Related questions




        • Java Strings: “String s = new String(”silly“);”

        • Strings are objects in Java, so why don’t we use ‘new’ to create them?




        What referential distinction means



        Examine the following snippet:



            String s1 = "foobar";
        String s2 = "foobar";

        System.out.println(s1 == s2); // true

        s2 = new String("foobar");
        System.out.println(s1 == s2); // false
        System.out.println(s1.equals(s2)); // true


        == on two reference types is a reference identity comparison. Two objects that are equals are not necessarily ==. It is usually wrong to use == on reference types; most of the time equals need to be used instead.



        Nonetheless, if for whatever reason you need to create two equals but not == string, you can use the new String(anotherString) constructor. It needs to be said again, however, that this is very peculiar, and is rarely the intention.



        References




        • JLS 15.21.3 Reference Equality Operators == and !=


        • class Object - boolean Object(equals)


        Related issues




        • Java String.equals versus ==

        • How do I compare strings in Java?






        share|improve this answer



















        • 3




          If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
          – Kaveesh Kanwal
          Apr 16 '15 at 18:34










        • Why nobody answer preceding question?
          – zeds
          Dec 1 '15 at 5:56






        • 2




          @KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2 "abc"s. Only one of them will go to the String pool, and the other one will refer to it. Then there's the s which will be proper new object.
          – Kayaman
          Mar 16 '16 at 11:21






        • 1




          @Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
          – user968813
          May 3 '16 at 7:38












        • There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
          – user207421
          Apr 24 at 11:45
















        163












        163








        163






        new String("text");
        explicitly creates a new and referentially distinct instance of a String object; String s = "text"; may reuse an instance from the string constant pool if one is available.



        You very rarely would ever want to use the new String(anotherString) constructor. From the API:




        String(String original) : Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since strings are immutable.




        Related questions




        • Java Strings: “String s = new String(”silly“);”

        • Strings are objects in Java, so why don’t we use ‘new’ to create them?




        What referential distinction means



        Examine the following snippet:



            String s1 = "foobar";
        String s2 = "foobar";

        System.out.println(s1 == s2); // true

        s2 = new String("foobar");
        System.out.println(s1 == s2); // false
        System.out.println(s1.equals(s2)); // true


        == on two reference types is a reference identity comparison. Two objects that are equals are not necessarily ==. It is usually wrong to use == on reference types; most of the time equals need to be used instead.



        Nonetheless, if for whatever reason you need to create two equals but not == string, you can use the new String(anotherString) constructor. It needs to be said again, however, that this is very peculiar, and is rarely the intention.



        References




        • JLS 15.21.3 Reference Equality Operators == and !=


        • class Object - boolean Object(equals)


        Related issues




        • Java String.equals versus ==

        • How do I compare strings in Java?






        share|improve this answer














        new String("text");
        explicitly creates a new and referentially distinct instance of a String object; String s = "text"; may reuse an instance from the string constant pool if one is available.



        You very rarely would ever want to use the new String(anotherString) constructor. From the API:




        String(String original) : Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since strings are immutable.




        Related questions




        • Java Strings: “String s = new String(”silly“);”

        • Strings are objects in Java, so why don’t we use ‘new’ to create them?




        What referential distinction means



        Examine the following snippet:



            String s1 = "foobar";
        String s2 = "foobar";

        System.out.println(s1 == s2); // true

        s2 = new String("foobar");
        System.out.println(s1 == s2); // false
        System.out.println(s1.equals(s2)); // true


        == on two reference types is a reference identity comparison. Two objects that are equals are not necessarily ==. It is usually wrong to use == on reference types; most of the time equals need to be used instead.



        Nonetheless, if for whatever reason you need to create two equals but not == string, you can use the new String(anotherString) constructor. It needs to be said again, however, that this is very peculiar, and is rarely the intention.



        References




        • JLS 15.21.3 Reference Equality Operators == and !=


        • class Object - boolean Object(equals)


        Related issues




        • Java String.equals versus ==

        • How do I compare strings in Java?







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited May 23 '17 at 11:54









        Community

        11




        11










        answered Jun 16 '10 at 10:30









        polygenelubricants

        280k101503591




        280k101503591








        • 3




          If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
          – Kaveesh Kanwal
          Apr 16 '15 at 18:34










        • Why nobody answer preceding question?
          – zeds
          Dec 1 '15 at 5:56






        • 2




          @KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2 "abc"s. Only one of them will go to the String pool, and the other one will refer to it. Then there's the s which will be proper new object.
          – Kayaman
          Mar 16 '16 at 11:21






        • 1




          @Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
          – user968813
          May 3 '16 at 7:38












        • There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
          – user207421
          Apr 24 at 11:45
















        • 3




          If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
          – Kaveesh Kanwal
          Apr 16 '15 at 18:34










        • Why nobody answer preceding question?
          – zeds
          Dec 1 '15 at 5:56






        • 2




          @KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2 "abc"s. Only one of them will go to the String pool, and the other one will refer to it. Then there's the s which will be proper new object.
          – Kayaman
          Mar 16 '16 at 11:21






        • 1




          @Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
          – user968813
          May 3 '16 at 7:38












        • There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
          – user207421
          Apr 24 at 11:45










        3




        3




        If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
        – Kaveesh Kanwal
        Apr 16 '15 at 18:34




        If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
        – Kaveesh Kanwal
        Apr 16 '15 at 18:34












        Why nobody answer preceding question?
        – zeds
        Dec 1 '15 at 5:56




        Why nobody answer preceding question?
        – zeds
        Dec 1 '15 at 5:56




        2




        2




        @KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2 "abc"s. Only one of them will go to the String pool, and the other one will refer to it. Then there's the s which will be proper new object.
        – Kayaman
        Mar 16 '16 at 11:21




        @KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2 "abc"s. Only one of them will go to the String pool, and the other one will refer to it. Then there's the s which will be proper new object.
        – Kayaman
        Mar 16 '16 at 11:21




        1




        1




        @Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
        – user968813
        May 3 '16 at 7:38






        @Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
        – user968813
        May 3 '16 at 7:38














        There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
        – user207421
        Apr 24 at 11:45






        There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
        – user207421
        Apr 24 at 11:45















        99














        String literals will go into String Constant Pool.



        The below snapshot might help you to understand it visually to remember it for longer time.



        enter image description here





        Object creation line by line:



        String str1 = new String("java5");


        Using string literal "java5" in the constructor, a new string value is stored in string constant pool.
        Using new operator, a new string object is created in the heap with "java5" as value.



        String str2 = "java5"


        Reference "str2" is pointed to already stored value in string constant pool



        String str3 = new String(str2);


        A new string object is created in the heap with the same value as reference by "str2"



        String str4 = "java5";


        Reference "str4" is pointed to already stored value in string constant pool



        Total objects : Heap - 2, Pool - 1



        Further reading on Oracle community






        share|improve this answer



















        • 1




          Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
          – CoronaPintu
          May 12 '14 at 8:25






        • 2




          yes i had check it will not change the value of str4
          – CoronaPintu
          May 12 '14 at 8:33










        • @Braj Can you provide documentation of your Answer’s assertion?
          – Basil Bourque
          Jul 1 '15 at 16:47










        • @Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
          – Rahul Kurup
          Aug 8 '15 at 10:52










        • Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
          – user207421
          Feb 7 '16 at 9:31
















        99














        String literals will go into String Constant Pool.



        The below snapshot might help you to understand it visually to remember it for longer time.



        enter image description here





        Object creation line by line:



        String str1 = new String("java5");


        Using string literal "java5" in the constructor, a new string value is stored in string constant pool.
        Using new operator, a new string object is created in the heap with "java5" as value.



        String str2 = "java5"


        Reference "str2" is pointed to already stored value in string constant pool



        String str3 = new String(str2);


        A new string object is created in the heap with the same value as reference by "str2"



        String str4 = "java5";


        Reference "str4" is pointed to already stored value in string constant pool



        Total objects : Heap - 2, Pool - 1



        Further reading on Oracle community






        share|improve this answer



















        • 1




          Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
          – CoronaPintu
          May 12 '14 at 8:25






        • 2




          yes i had check it will not change the value of str4
          – CoronaPintu
          May 12 '14 at 8:33










        • @Braj Can you provide documentation of your Answer’s assertion?
          – Basil Bourque
          Jul 1 '15 at 16:47










        • @Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
          – Rahul Kurup
          Aug 8 '15 at 10:52










        • Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
          – user207421
          Feb 7 '16 at 9:31














        99












        99








        99






        String literals will go into String Constant Pool.



        The below snapshot might help you to understand it visually to remember it for longer time.



        enter image description here





        Object creation line by line:



        String str1 = new String("java5");


        Using string literal "java5" in the constructor, a new string value is stored in string constant pool.
        Using new operator, a new string object is created in the heap with "java5" as value.



        String str2 = "java5"


        Reference "str2" is pointed to already stored value in string constant pool



        String str3 = new String(str2);


        A new string object is created in the heap with the same value as reference by "str2"



        String str4 = "java5";


        Reference "str4" is pointed to already stored value in string constant pool



        Total objects : Heap - 2, Pool - 1



        Further reading on Oracle community






        share|improve this answer














        String literals will go into String Constant Pool.



        The below snapshot might help you to understand it visually to remember it for longer time.



        enter image description here





        Object creation line by line:



        String str1 = new String("java5");


        Using string literal "java5" in the constructor, a new string value is stored in string constant pool.
        Using new operator, a new string object is created in the heap with "java5" as value.



        String str2 = "java5"


        Reference "str2" is pointed to already stored value in string constant pool



        String str3 = new String(str2);


        A new string object is created in the heap with the same value as reference by "str2"



        String str4 = "java5";


        Reference "str4" is pointed to already stored value in string constant pool



        Total objects : Heap - 2, Pool - 1



        Further reading on Oracle community







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 14 at 14:02









        Lucky

        10.4k1074113




        10.4k1074113










        answered May 8 '14 at 15:26









        Braj

        40.3k43658




        40.3k43658








        • 1




          Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
          – CoronaPintu
          May 12 '14 at 8:25






        • 2




          yes i had check it will not change the value of str4
          – CoronaPintu
          May 12 '14 at 8:33










        • @Braj Can you provide documentation of your Answer’s assertion?
          – Basil Bourque
          Jul 1 '15 at 16:47










        • @Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
          – Rahul Kurup
          Aug 8 '15 at 10:52










        • Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
          – user207421
          Feb 7 '16 at 9:31














        • 1




          Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
          – CoronaPintu
          May 12 '14 at 8:25






        • 2




          yes i had check it will not change the value of str4
          – CoronaPintu
          May 12 '14 at 8:33










        • @Braj Can you provide documentation of your Answer’s assertion?
          – Basil Bourque
          Jul 1 '15 at 16:47










        • @Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
          – Rahul Kurup
          Aug 8 '15 at 10:52










        • Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
          – user207421
          Feb 7 '16 at 9:31








        1




        1




        Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
        – CoronaPintu
        May 12 '14 at 8:25




        Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
        – CoronaPintu
        May 12 '14 at 8:25




        2




        2




        yes i had check it will not change the value of str4
        – CoronaPintu
        May 12 '14 at 8:33




        yes i had check it will not change the value of str4
        – CoronaPintu
        May 12 '14 at 8:33












        @Braj Can you provide documentation of your Answer’s assertion?
        – Basil Bourque
        Jul 1 '15 at 16:47




        @Braj Can you provide documentation of your Answer’s assertion?
        – Basil Bourque
        Jul 1 '15 at 16:47












        @Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
        – Rahul Kurup
        Aug 8 '15 at 10:52




        @Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
        – Rahul Kurup
        Aug 8 '15 at 10:52












        Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
        – user207421
        Feb 7 '16 at 9:31




        Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
        – user207421
        Feb 7 '16 at 9:31











        15














        One creates a String in the String Constant Pool



        String s = "text";


        the other one creates a string in the constant pool ("text") and another string in normal heap space (s). Both strings will have the same value, that of "text".



        String s = new String("text");


        s is then lost (eligible for GC) if later unused.



        String literals on the other hand are reused. If you use "text" in multiple places of your class it will in fact be one and only one String (i.e. multiple references to the same string in the pool).






        share|improve this answer























        • Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
          – user207421
          Jun 16 '10 at 10:38












        • @EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
          – user159088
          Jun 16 '10 at 10:43
















        15














        One creates a String in the String Constant Pool



        String s = "text";


        the other one creates a string in the constant pool ("text") and another string in normal heap space (s). Both strings will have the same value, that of "text".



        String s = new String("text");


        s is then lost (eligible for GC) if later unused.



        String literals on the other hand are reused. If you use "text" in multiple places of your class it will in fact be one and only one String (i.e. multiple references to the same string in the pool).






        share|improve this answer























        • Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
          – user207421
          Jun 16 '10 at 10:38












        • @EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
          – user159088
          Jun 16 '10 at 10:43














        15












        15








        15






        One creates a String in the String Constant Pool



        String s = "text";


        the other one creates a string in the constant pool ("text") and another string in normal heap space (s). Both strings will have the same value, that of "text".



        String s = new String("text");


        s is then lost (eligible for GC) if later unused.



        String literals on the other hand are reused. If you use "text" in multiple places of your class it will in fact be one and only one String (i.e. multiple references to the same string in the pool).






        share|improve this answer














        One creates a String in the String Constant Pool



        String s = "text";


        the other one creates a string in the constant pool ("text") and another string in normal heap space (s). Both strings will have the same value, that of "text".



        String s = new String("text");


        s is then lost (eligible for GC) if later unused.



        String literals on the other hand are reused. If you use "text" in multiple places of your class it will in fact be one and only one String (i.e. multiple references to the same string in the pool).







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jun 16 '10 at 11:57

























        answered Jun 16 '10 at 10:32







        user159088



















        • Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
          – user207421
          Jun 16 '10 at 10:38












        • @EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
          – user159088
          Jun 16 '10 at 10:43


















        • Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
          – user207421
          Jun 16 '10 at 10:38












        • @EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
          – user159088
          Jun 16 '10 at 10:43
















        Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
        – user207421
        Jun 16 '10 at 10:38






        Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
        – user207421
        Jun 16 '10 at 10:38














        @EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
        – user159088
        Jun 16 '10 at 10:43




        @EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
        – user159088
        Jun 16 '10 at 10:43











        8














        JLS



        The concept is called "interning" by the JLS.



        Relevant passage from JLS 7 3.10.5:




        Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.



        Example 3.10.5-1. String Literals



        The program consisting of the compilation unit (§7.3):



        package testPackage;
        class Test {
        public static void main(String args) {
        String hello = "Hello", lo = "lo";
        System.out.print((hello == "Hello") + " ");
        System.out.print((Other.hello == hello) + " ");
        System.out.print((other.Other.hello == hello) + " ");
        System.out.print((hello == ("Hel"+"lo")) + " ");
        System.out.print((hello == ("Hel"+lo)) + " ");
        System.out.println(hello == ("Hel"+lo).intern());
        }
        }
        class Other { static String hello = "Hello"; }


        and the compilation unit:



        package other;
        public class Other { public static String hello = "Hello"; }


        produces the output:



        true true true true false true



        JVMS



        JVMS 7 5.1 says:




        A string literal is a reference to an instance of class String, and is derived from a CONSTANT_String_info structure (§4.4.3) in the binary representation of a class or interface. The CONSTANT_String_info structure gives the sequence of Unicode code points constituting the string literal.



        The Java programming language requires that identical string literals (that is, literals that contain the same sequence of code points) must refer to the same instance of class String (JLS §3.10.5). In addition, if the method String.intern is called on any string, the result is a reference to the same class instance that would be returned if that string appeared as a literal. Thus, the following expression must have the value true:



        ("a" + "b" + "c").intern() == "abc"


        To derive a string literal, the Java Virtual Machine examines the sequence of code points given by the CONSTANT_String_info structure.




        • If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String.


        • Otherwise, a new instance of class String is created containing the sequence of Unicode code points given by the CONSTANT_String_info structure; a reference to that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.





        Bytecode



        It is also instructive to look at the bytecode implementation on OpenJDK 7.



        If we decompile:



        public class StringPool {
        public static void main(String args) {
        String a = "abc";
        String b = "abc";
        String c = new String("abc");
        System.out.println(a);
        System.out.println(b);
        System.out.println(a == c);
        }
        }


        we have on the constant pool:



        #2 = String             #32   // abc
        [...]
        #32 = Utf8 abc


        and main:



         0: ldc           #2          // String abc
        2: astore_1
        3: ldc #2 // String abc
        5: astore_2
        6: new #3 // class java/lang/String
        9: dup
        10: ldc #2 // String abc
        12: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
        15: astore_3
        16: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
        19: aload_1
        20: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        23: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
        26: aload_2
        27: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        30: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
        33: aload_1
        34: aload_3
        35: if_acmpne 42
        38: iconst_1
        39: goto 43
        42: iconst_0
        43: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V


        Note how:





        • 0 and 3: the same ldc #2 constant is loaded (the literals)


        • 12: a new string instance is created (with #2 as argument)


        • 35: a and c are compared as regular objects with if_acmpne


        The representation of constant strings is quite magic on the bytecode:




        • it has a dedicated CONSTANT_String_info structure, unlike regular objects (e.g. new String)

        • the struct points to a CONSTANT_Utf8_info Structure that contains the data. That is the only necessary data to represent the string.


        and the JVMS quote above seems to say that whenever the Utf8 pointed to is the same, then identical instances are loaded by ldc.



        I have done similar tests for fields, and:





        • static final String s = "abc" points to the constant table through the ConstantValue Attribute

        • non-final fields don't have that attribute, but can still be initialized with ldc


        Conclusion: there is direct bytecode support for the string pool, and the memory representation is efficient.



        Bonus: compare that to the Integer pool, which does not have direct bytecode support (i.e. no CONSTANT_String_info analogue).






        share|improve this answer




























          8














          JLS



          The concept is called "interning" by the JLS.



          Relevant passage from JLS 7 3.10.5:




          Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.



          Example 3.10.5-1. String Literals



          The program consisting of the compilation unit (§7.3):



          package testPackage;
          class Test {
          public static void main(String args) {
          String hello = "Hello", lo = "lo";
          System.out.print((hello == "Hello") + " ");
          System.out.print((Other.hello == hello) + " ");
          System.out.print((other.Other.hello == hello) + " ");
          System.out.print((hello == ("Hel"+"lo")) + " ");
          System.out.print((hello == ("Hel"+lo)) + " ");
          System.out.println(hello == ("Hel"+lo).intern());
          }
          }
          class Other { static String hello = "Hello"; }


          and the compilation unit:



          package other;
          public class Other { public static String hello = "Hello"; }


          produces the output:



          true true true true false true



          JVMS



          JVMS 7 5.1 says:




          A string literal is a reference to an instance of class String, and is derived from a CONSTANT_String_info structure (§4.4.3) in the binary representation of a class or interface. The CONSTANT_String_info structure gives the sequence of Unicode code points constituting the string literal.



          The Java programming language requires that identical string literals (that is, literals that contain the same sequence of code points) must refer to the same instance of class String (JLS §3.10.5). In addition, if the method String.intern is called on any string, the result is a reference to the same class instance that would be returned if that string appeared as a literal. Thus, the following expression must have the value true:



          ("a" + "b" + "c").intern() == "abc"


          To derive a string literal, the Java Virtual Machine examines the sequence of code points given by the CONSTANT_String_info structure.




          • If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String.


          • Otherwise, a new instance of class String is created containing the sequence of Unicode code points given by the CONSTANT_String_info structure; a reference to that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.





          Bytecode



          It is also instructive to look at the bytecode implementation on OpenJDK 7.



          If we decompile:



          public class StringPool {
          public static void main(String args) {
          String a = "abc";
          String b = "abc";
          String c = new String("abc");
          System.out.println(a);
          System.out.println(b);
          System.out.println(a == c);
          }
          }


          we have on the constant pool:



          #2 = String             #32   // abc
          [...]
          #32 = Utf8 abc


          and main:



           0: ldc           #2          // String abc
          2: astore_1
          3: ldc #2 // String abc
          5: astore_2
          6: new #3 // class java/lang/String
          9: dup
          10: ldc #2 // String abc
          12: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
          15: astore_3
          16: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
          19: aload_1
          20: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          23: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
          26: aload_2
          27: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
          30: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
          33: aload_1
          34: aload_3
          35: if_acmpne 42
          38: iconst_1
          39: goto 43
          42: iconst_0
          43: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V


          Note how:





          • 0 and 3: the same ldc #2 constant is loaded (the literals)


          • 12: a new string instance is created (with #2 as argument)


          • 35: a and c are compared as regular objects with if_acmpne


          The representation of constant strings is quite magic on the bytecode:




          • it has a dedicated CONSTANT_String_info structure, unlike regular objects (e.g. new String)

          • the struct points to a CONSTANT_Utf8_info Structure that contains the data. That is the only necessary data to represent the string.


          and the JVMS quote above seems to say that whenever the Utf8 pointed to is the same, then identical instances are loaded by ldc.



          I have done similar tests for fields, and:





          • static final String s = "abc" points to the constant table through the ConstantValue Attribute

          • non-final fields don't have that attribute, but can still be initialized with ldc


          Conclusion: there is direct bytecode support for the string pool, and the memory representation is efficient.



          Bonus: compare that to the Integer pool, which does not have direct bytecode support (i.e. no CONSTANT_String_info analogue).






          share|improve this answer


























            8












            8








            8






            JLS



            The concept is called "interning" by the JLS.



            Relevant passage from JLS 7 3.10.5:




            Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.



            Example 3.10.5-1. String Literals



            The program consisting of the compilation unit (§7.3):



            package testPackage;
            class Test {
            public static void main(String args) {
            String hello = "Hello", lo = "lo";
            System.out.print((hello == "Hello") + " ");
            System.out.print((Other.hello == hello) + " ");
            System.out.print((other.Other.hello == hello) + " ");
            System.out.print((hello == ("Hel"+"lo")) + " ");
            System.out.print((hello == ("Hel"+lo)) + " ");
            System.out.println(hello == ("Hel"+lo).intern());
            }
            }
            class Other { static String hello = "Hello"; }


            and the compilation unit:



            package other;
            public class Other { public static String hello = "Hello"; }


            produces the output:



            true true true true false true



            JVMS



            JVMS 7 5.1 says:




            A string literal is a reference to an instance of class String, and is derived from a CONSTANT_String_info structure (§4.4.3) in the binary representation of a class or interface. The CONSTANT_String_info structure gives the sequence of Unicode code points constituting the string literal.



            The Java programming language requires that identical string literals (that is, literals that contain the same sequence of code points) must refer to the same instance of class String (JLS §3.10.5). In addition, if the method String.intern is called on any string, the result is a reference to the same class instance that would be returned if that string appeared as a literal. Thus, the following expression must have the value true:



            ("a" + "b" + "c").intern() == "abc"


            To derive a string literal, the Java Virtual Machine examines the sequence of code points given by the CONSTANT_String_info structure.




            • If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String.


            • Otherwise, a new instance of class String is created containing the sequence of Unicode code points given by the CONSTANT_String_info structure; a reference to that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.





            Bytecode



            It is also instructive to look at the bytecode implementation on OpenJDK 7.



            If we decompile:



            public class StringPool {
            public static void main(String args) {
            String a = "abc";
            String b = "abc";
            String c = new String("abc");
            System.out.println(a);
            System.out.println(b);
            System.out.println(a == c);
            }
            }


            we have on the constant pool:



            #2 = String             #32   // abc
            [...]
            #32 = Utf8 abc


            and main:



             0: ldc           #2          // String abc
            2: astore_1
            3: ldc #2 // String abc
            5: astore_2
            6: new #3 // class java/lang/String
            9: dup
            10: ldc #2 // String abc
            12: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
            15: astore_3
            16: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
            19: aload_1
            20: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            23: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
            26: aload_2
            27: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            30: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
            33: aload_1
            34: aload_3
            35: if_acmpne 42
            38: iconst_1
            39: goto 43
            42: iconst_0
            43: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V


            Note how:





            • 0 and 3: the same ldc #2 constant is loaded (the literals)


            • 12: a new string instance is created (with #2 as argument)


            • 35: a and c are compared as regular objects with if_acmpne


            The representation of constant strings is quite magic on the bytecode:




            • it has a dedicated CONSTANT_String_info structure, unlike regular objects (e.g. new String)

            • the struct points to a CONSTANT_Utf8_info Structure that contains the data. That is the only necessary data to represent the string.


            and the JVMS quote above seems to say that whenever the Utf8 pointed to is the same, then identical instances are loaded by ldc.



            I have done similar tests for fields, and:





            • static final String s = "abc" points to the constant table through the ConstantValue Attribute

            • non-final fields don't have that attribute, but can still be initialized with ldc


            Conclusion: there is direct bytecode support for the string pool, and the memory representation is efficient.



            Bonus: compare that to the Integer pool, which does not have direct bytecode support (i.e. no CONSTANT_String_info analogue).






            share|improve this answer














            JLS



            The concept is called "interning" by the JLS.



            Relevant passage from JLS 7 3.10.5:




            Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.



            Example 3.10.5-1. String Literals



            The program consisting of the compilation unit (§7.3):



            package testPackage;
            class Test {
            public static void main(String args) {
            String hello = "Hello", lo = "lo";
            System.out.print((hello == "Hello") + " ");
            System.out.print((Other.hello == hello) + " ");
            System.out.print((other.Other.hello == hello) + " ");
            System.out.print((hello == ("Hel"+"lo")) + " ");
            System.out.print((hello == ("Hel"+lo)) + " ");
            System.out.println(hello == ("Hel"+lo).intern());
            }
            }
            class Other { static String hello = "Hello"; }


            and the compilation unit:



            package other;
            public class Other { public static String hello = "Hello"; }


            produces the output:



            true true true true false true



            JVMS



            JVMS 7 5.1 says:




            A string literal is a reference to an instance of class String, and is derived from a CONSTANT_String_info structure (§4.4.3) in the binary representation of a class or interface. The CONSTANT_String_info structure gives the sequence of Unicode code points constituting the string literal.



            The Java programming language requires that identical string literals (that is, literals that contain the same sequence of code points) must refer to the same instance of class String (JLS §3.10.5). In addition, if the method String.intern is called on any string, the result is a reference to the same class instance that would be returned if that string appeared as a literal. Thus, the following expression must have the value true:



            ("a" + "b" + "c").intern() == "abc"


            To derive a string literal, the Java Virtual Machine examines the sequence of code points given by the CONSTANT_String_info structure.




            • If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String.


            • Otherwise, a new instance of class String is created containing the sequence of Unicode code points given by the CONSTANT_String_info structure; a reference to that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.





            Bytecode



            It is also instructive to look at the bytecode implementation on OpenJDK 7.



            If we decompile:



            public class StringPool {
            public static void main(String args) {
            String a = "abc";
            String b = "abc";
            String c = new String("abc");
            System.out.println(a);
            System.out.println(b);
            System.out.println(a == c);
            }
            }


            we have on the constant pool:



            #2 = String             #32   // abc
            [...]
            #32 = Utf8 abc


            and main:



             0: ldc           #2          // String abc
            2: astore_1
            3: ldc #2 // String abc
            5: astore_2
            6: new #3 // class java/lang/String
            9: dup
            10: ldc #2 // String abc
            12: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
            15: astore_3
            16: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
            19: aload_1
            20: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            23: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
            26: aload_2
            27: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            30: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
            33: aload_1
            34: aload_3
            35: if_acmpne 42
            38: iconst_1
            39: goto 43
            42: iconst_0
            43: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V


            Note how:





            • 0 and 3: the same ldc #2 constant is loaded (the literals)


            • 12: a new string instance is created (with #2 as argument)


            • 35: a and c are compared as regular objects with if_acmpne


            The representation of constant strings is quite magic on the bytecode:




            • it has a dedicated CONSTANT_String_info structure, unlike regular objects (e.g. new String)

            • the struct points to a CONSTANT_Utf8_info Structure that contains the data. That is the only necessary data to represent the string.


            and the JVMS quote above seems to say that whenever the Utf8 pointed to is the same, then identical instances are loaded by ldc.



            I have done similar tests for fields, and:





            • static final String s = "abc" points to the constant table through the ConstantValue Attribute

            • non-final fields don't have that attribute, but can still be initialized with ldc


            Conclusion: there is direct bytecode support for the string pool, and the memory representation is efficient.



            Bonus: compare that to the Integer pool, which does not have direct bytecode support (i.e. no CONSTANT_String_info analogue).







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jul 28 '17 at 16:59

























            answered Apr 15 '17 at 7:18









            Ciro Santilli 新疆改造中心 六四事件 法轮功

            134k30524451




            134k30524451























                1














                Think of "bla" being a magic factory like Strings.createString("bla") (pseudo). The factory holds a pool of all strings yet created this way.



                If it gets invoked, it checks if there is already string in the pool with this value. If true, it returns this string object, hence to strings obtained this way are indeed the same object.



                If not, it creates a new string object internally, saves it in the pool and then returns it. Thus, when the same string value is queried the next time, it returns the same instance.



                Manually creating new String("") overrides this behaviour by bypassing the string literal pool. So equality should always be checked using equals() which compares the character sequence instead of the object reference equality.






                share|improve this answer





















                • The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
                  – user207421
                  Feb 7 '16 at 9:20


















                1














                Think of "bla" being a magic factory like Strings.createString("bla") (pseudo). The factory holds a pool of all strings yet created this way.



                If it gets invoked, it checks if there is already string in the pool with this value. If true, it returns this string object, hence to strings obtained this way are indeed the same object.



                If not, it creates a new string object internally, saves it in the pool and then returns it. Thus, when the same string value is queried the next time, it returns the same instance.



                Manually creating new String("") overrides this behaviour by bypassing the string literal pool. So equality should always be checked using equals() which compares the character sequence instead of the object reference equality.






                share|improve this answer





















                • The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
                  – user207421
                  Feb 7 '16 at 9:20
















                1












                1








                1






                Think of "bla" being a magic factory like Strings.createString("bla") (pseudo). The factory holds a pool of all strings yet created this way.



                If it gets invoked, it checks if there is already string in the pool with this value. If true, it returns this string object, hence to strings obtained this way are indeed the same object.



                If not, it creates a new string object internally, saves it in the pool and then returns it. Thus, when the same string value is queried the next time, it returns the same instance.



                Manually creating new String("") overrides this behaviour by bypassing the string literal pool. So equality should always be checked using equals() which compares the character sequence instead of the object reference equality.






                share|improve this answer












                Think of "bla" being a magic factory like Strings.createString("bla") (pseudo). The factory holds a pool of all strings yet created this way.



                If it gets invoked, it checks if there is already string in the pool with this value. If true, it returns this string object, hence to strings obtained this way are indeed the same object.



                If not, it creates a new string object internally, saves it in the pool and then returns it. Thus, when the same string value is queried the next time, it returns the same instance.



                Manually creating new String("") overrides this behaviour by bypassing the string literal pool. So equality should always be checked using equals() which compares the character sequence instead of the object reference equality.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jun 16 '10 at 10:46









                b_erb

                15.9k84461




                15.9k84461












                • The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
                  – user207421
                  Feb 7 '16 at 9:20




















                • The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
                  – user207421
                  Feb 7 '16 at 9:20


















                The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
                – user207421
                Feb 7 '16 at 9:20






                The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
                – user207421
                Feb 7 '16 at 9:20













                1














                One simple way to understand the difference is below:-



                String s ="abc";
                String s1= "abc";
                String s2=new String("abc");

                if(s==s1){
                System.out.println("s==s1 is true");
                }else{
                System.out.println("s==s1 is false");
                }
                if(s==s2){
                System.out.println("s==s2 is true");
                }else{
                System.out.println("s==s2 is false");
                }


                output is



                s==s1 is true
                s==s2 is false


                Thus new String() will always create a new instance.






                share|improve this answer


























                  1














                  One simple way to understand the difference is below:-



                  String s ="abc";
                  String s1= "abc";
                  String s2=new String("abc");

                  if(s==s1){
                  System.out.println("s==s1 is true");
                  }else{
                  System.out.println("s==s1 is false");
                  }
                  if(s==s2){
                  System.out.println("s==s2 is true");
                  }else{
                  System.out.println("s==s2 is false");
                  }


                  output is



                  s==s1 is true
                  s==s2 is false


                  Thus new String() will always create a new instance.






                  share|improve this answer
























                    1












                    1








                    1






                    One simple way to understand the difference is below:-



                    String s ="abc";
                    String s1= "abc";
                    String s2=new String("abc");

                    if(s==s1){
                    System.out.println("s==s1 is true");
                    }else{
                    System.out.println("s==s1 is false");
                    }
                    if(s==s2){
                    System.out.println("s==s2 is true");
                    }else{
                    System.out.println("s==s2 is false");
                    }


                    output is



                    s==s1 is true
                    s==s2 is false


                    Thus new String() will always create a new instance.






                    share|improve this answer












                    One simple way to understand the difference is below:-



                    String s ="abc";
                    String s1= "abc";
                    String s2=new String("abc");

                    if(s==s1){
                    System.out.println("s==s1 is true");
                    }else{
                    System.out.println("s==s1 is false");
                    }
                    if(s==s2){
                    System.out.println("s==s2 is true");
                    }else{
                    System.out.println("s==s2 is false");
                    }


                    output is



                    s==s1 is true
                    s==s2 is false


                    Thus new String() will always create a new instance.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Jun 16 '10 at 11:19









                    Shashank T

                    479159




                    479159























                        1














                        @Braj : i think u have mentioned the other way around. Please correct me if i am wrong



                        Object creation line by line:



                        String str1 = new String("java5")



                           Pool- "java5" (1 Object)

                        Heap - str1 => "java5" (1 Object)


                        String str2 = "java5"



                          pool- str2 => "java5" (1 Object)

                        heap - str1 => "java5" (1 Object)


                        String str3 = new String(str2)



                          pool- str2 => "java5" (1 Object)

                        heap- str1 => "java5", str3 => "java5" (2 Objects)


                        String str4 = "java5"



                          pool - str2 => str4 => "java5" (1 Object)

                        heap - str1 => "java5", str3 => "java5" (2 Objects)





                        share|improve this answer





















                        • str1 is not involved in the value of str2 or str3 or str4 in any way.
                          – user207421
                          Feb 7 '16 at 9:24
















                        1














                        @Braj : i think u have mentioned the other way around. Please correct me if i am wrong



                        Object creation line by line:



                        String str1 = new String("java5")



                           Pool- "java5" (1 Object)

                        Heap - str1 => "java5" (1 Object)


                        String str2 = "java5"



                          pool- str2 => "java5" (1 Object)

                        heap - str1 => "java5" (1 Object)


                        String str3 = new String(str2)



                          pool- str2 => "java5" (1 Object)

                        heap- str1 => "java5", str3 => "java5" (2 Objects)


                        String str4 = "java5"



                          pool - str2 => str4 => "java5" (1 Object)

                        heap - str1 => "java5", str3 => "java5" (2 Objects)





                        share|improve this answer





















                        • str1 is not involved in the value of str2 or str3 or str4 in any way.
                          – user207421
                          Feb 7 '16 at 9:24














                        1












                        1








                        1






                        @Braj : i think u have mentioned the other way around. Please correct me if i am wrong



                        Object creation line by line:



                        String str1 = new String("java5")



                           Pool- "java5" (1 Object)

                        Heap - str1 => "java5" (1 Object)


                        String str2 = "java5"



                          pool- str2 => "java5" (1 Object)

                        heap - str1 => "java5" (1 Object)


                        String str3 = new String(str2)



                          pool- str2 => "java5" (1 Object)

                        heap- str1 => "java5", str3 => "java5" (2 Objects)


                        String str4 = "java5"



                          pool - str2 => str4 => "java5" (1 Object)

                        heap - str1 => "java5", str3 => "java5" (2 Objects)





                        share|improve this answer












                        @Braj : i think u have mentioned the other way around. Please correct me if i am wrong



                        Object creation line by line:



                        String str1 = new String("java5")



                           Pool- "java5" (1 Object)

                        Heap - str1 => "java5" (1 Object)


                        String str2 = "java5"



                          pool- str2 => "java5" (1 Object)

                        heap - str1 => "java5" (1 Object)


                        String str3 = new String(str2)



                          pool- str2 => "java5" (1 Object)

                        heap- str1 => "java5", str3 => "java5" (2 Objects)


                        String str4 = "java5"



                          pool - str2 => str4 => "java5" (1 Object)

                        heap - str1 => "java5", str3 => "java5" (2 Objects)






                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Jul 7 '15 at 2:32









                        SDC

                        4610




                        4610












                        • str1 is not involved in the value of str2 or str3 or str4 in any way.
                          – user207421
                          Feb 7 '16 at 9:24


















                        • str1 is not involved in the value of str2 or str3 or str4 in any way.
                          – user207421
                          Feb 7 '16 at 9:24
















                        str1 is not involved in the value of str2 or str3 or str4 in any way.
                        – user207421
                        Feb 7 '16 at 9:24




                        str1 is not involved in the value of str2 or str3 or str4 in any way.
                        – user207421
                        Feb 7 '16 at 9:24











                        0














                        Although it looks the same from a programmers point of view, it has big performance impact. You would want to use the first form almost always.






                        share|improve this answer


























                          0














                          Although it looks the same from a programmers point of view, it has big performance impact. You would want to use the first form almost always.






                          share|improve this answer
























                            0












                            0








                            0






                            Although it looks the same from a programmers point of view, it has big performance impact. You would want to use the first form almost always.






                            share|improve this answer












                            Although it looks the same from a programmers point of view, it has big performance impact. You would want to use the first form almost always.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Jun 17 '10 at 4:38









                            fastcodejava

                            23.8k19109160




                            23.8k19109160























                                0














                                String str = new String("hello")


                                It will check whether String constant pool already contains String "hello"?
                                If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.



                                An object will be created in a heap memory area and str reference points to object created in heap memory location.



                                if you want str reference to point object containing in String constant pool then one has to explicitly call str.intern();



                                String str = "world";


                                It will check whether String constant pool already contains String "hello"?
                                If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.



                                In both the above case, str reference points to String "world" present in Constant pool.






                                share|improve this answer





















                                • 'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
                                  – user207421
                                  Feb 7 '16 at 9:28










                                • Can you please explain what is wrong in this post clearly?
                                  – Jayesh
                                  Feb 7 '16 at 9:46










                                • What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
                                  – user207421
                                  Oct 22 '16 at 7:22










                                • @EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
                                  – Jayesh
                                  Oct 22 '16 at 7:43










                                • You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
                                  – user207421
                                  Aug 23 '17 at 4:02


















                                0














                                String str = new String("hello")


                                It will check whether String constant pool already contains String "hello"?
                                If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.



                                An object will be created in a heap memory area and str reference points to object created in heap memory location.



                                if you want str reference to point object containing in String constant pool then one has to explicitly call str.intern();



                                String str = "world";


                                It will check whether String constant pool already contains String "hello"?
                                If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.



                                In both the above case, str reference points to String "world" present in Constant pool.






                                share|improve this answer





















                                • 'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
                                  – user207421
                                  Feb 7 '16 at 9:28










                                • Can you please explain what is wrong in this post clearly?
                                  – Jayesh
                                  Feb 7 '16 at 9:46










                                • What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
                                  – user207421
                                  Oct 22 '16 at 7:22










                                • @EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
                                  – Jayesh
                                  Oct 22 '16 at 7:43










                                • You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
                                  – user207421
                                  Aug 23 '17 at 4:02
















                                0












                                0








                                0






                                String str = new String("hello")


                                It will check whether String constant pool already contains String "hello"?
                                If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.



                                An object will be created in a heap memory area and str reference points to object created in heap memory location.



                                if you want str reference to point object containing in String constant pool then one has to explicitly call str.intern();



                                String str = "world";


                                It will check whether String constant pool already contains String "hello"?
                                If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.



                                In both the above case, str reference points to String "world" present in Constant pool.






                                share|improve this answer












                                String str = new String("hello")


                                It will check whether String constant pool already contains String "hello"?
                                If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.



                                An object will be created in a heap memory area and str reference points to object created in heap memory location.



                                if you want str reference to point object containing in String constant pool then one has to explicitly call str.intern();



                                String str = "world";


                                It will check whether String constant pool already contains String "hello"?
                                If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.



                                In both the above case, str reference points to String "world" present in Constant pool.







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Sep 15 '15 at 10:24









                                Jayesh

                                3,14573767




                                3,14573767












                                • 'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
                                  – user207421
                                  Feb 7 '16 at 9:28










                                • Can you please explain what is wrong in this post clearly?
                                  – Jayesh
                                  Feb 7 '16 at 9:46










                                • What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
                                  – user207421
                                  Oct 22 '16 at 7:22










                                • @EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
                                  – Jayesh
                                  Oct 22 '16 at 7:43










                                • You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
                                  – user207421
                                  Aug 23 '17 at 4:02




















                                • 'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
                                  – user207421
                                  Feb 7 '16 at 9:28










                                • Can you please explain what is wrong in this post clearly?
                                  – Jayesh
                                  Feb 7 '16 at 9:46










                                • What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
                                  – user207421
                                  Oct 22 '16 at 7:22










                                • @EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
                                  – Jayesh
                                  Oct 22 '16 at 7:43










                                • You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
                                  – user207421
                                  Aug 23 '17 at 4:02


















                                'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
                                – user207421
                                Feb 7 '16 at 9:28




                                'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
                                – user207421
                                Feb 7 '16 at 9:28












                                Can you please explain what is wrong in this post clearly?
                                – Jayesh
                                Feb 7 '16 at 9:46




                                Can you please explain what is wrong in this post clearly?
                                – Jayesh
                                Feb 7 '16 at 9:46












                                What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
                                – user207421
                                Oct 22 '16 at 7:22




                                What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
                                – user207421
                                Oct 22 '16 at 7:22












                                @EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
                                – Jayesh
                                Oct 22 '16 at 7:43




                                @EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
                                – Jayesh
                                Oct 22 '16 at 7:43












                                You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
                                – user207421
                                Aug 23 '17 at 4:02






                                You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
                                – user207421
                                Aug 23 '17 at 4:02







                                protected by ΦXocę 웃 Пepeúpa ツ Sep 8 '17 at 5:49



                                Thank you for your interest in this question.
                                Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                                Would you like to answer one of these unanswered questions instead?



                                Popular posts from this blog

                                Xamarin.iOS Cant Deploy on Iphone

                                Glorious Revolution

                                Dulmage-Mendelsohn matrix decomposition in Python