This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes Beginning Java and the fly likes The well known String str = Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "The well known String str = "abc" and String str1 = new String("abc");" Watch "The well known String str = "abc" and String str1 = new String("abc");" New topic
Author

The well known String str = "abc" and String str1 = new String("abc");

ram kumar
Ranch Hand

Joined: May 22, 2008
Posts: 146
String str = "abc" and String str1 = new String("abc");

What happens in the first case > String str = "abc" ?

Is that getting allocated to the String constant pool !

What happens in the Second case > String str1 = new String("abc");

The String str1 = abc is allocated in the String constant pool.

Then str1 is copied to the new Memory space allocated, by the new Operator!

So same string "abc" for str1 is available in 2 locations.

location 1:str1 = "abc" - string constants pool

location 2:str1 = new String("abc"); in the object heap memory

Am i right about all above statements !

I verified in net but still not in a position understand clearly.

PLease cross verify me.

thanks for the support!


Discussion - the powerfull way to excellence!
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38062
    
  22
Originally posted by ram kumar:
String str = "abc" and String str1 = new String("abc");

What happens in the first case > String str = "abc" ?

Is that getting allocated to the String constant pool !
No. "abc" is already in the constant pool and it is simply given a name (identifier). The String literal is put into the String pool when the class is loaded and the identifier assigned when that method is executed.
What happens in the Second case > String str1 = new String("abc");

The String str1 = abc is allocated in the String constant pool.
No. "abc" is still in the constant pool; new creates another String object with the same contents.
Then str1 is copied to the new Memory space allocated, by the new Operator!
No. A String is created which happens to have the same contents.
So same string "abc" for str1 is available in 2 locations.

location 1:str1 = "abc" - string constants pool

location 2:str1 = new String("abc"); in the object heap memory
No. You now have two different Strings which contain the same value.
Am i right about all above statements !

I verified in net but still not in a position understand clearly.

PLease cross verify me.

thanks for the support!
At least I think that is what happens. Careful where you verify things. JavaRanch is reliable; if I am mistaken somebody will tell you within the hour.
Justin Fox
Ranch Hand

Joined: Jan 24, 2006
Posts: 802
I thought that the string was only in the pool?, and that the heap in memory was just a reference to that string in the pool. so actually you only have one string, and just another reference to it through the new operator of the string class.

because if you do:



I think it puts "hello" in the string pool when String 'a' is declared, and then when 'b' is declare through the 'new' constructor, it just makes an object reference to the existing string 'hello' in the pool. So you dont have inefficient code with tons of duplicates in the string pool.

so even though a and b are different string object, the point to the same reference.

is this right?

Justin Fox
[ June 26, 2008: Message edited by: Justin Fox ]

You down with OOP? Yeah you know me!
ram kumar
Ranch Hand

Joined: May 22, 2008
Posts: 146
Originally posted by Justin Fox:
I thought that the string was only in the pool?, and that the heap in memory was just a reference to that string in the pool. so actually you only have one string, and just another reference to it through the new operator of the string class.

because if you do:



I think it puts "hello" in the string pool when String 'a' is declared, and then when 'b' is declare through the 'new' constructor, it just makes an object reference to the existing string 'hello' in the pool. So you dont have inefficient code with tons of duplicates in the string pool.

so even though a and b are different string object, the point to the same reference.

is this right?

Justin Fox

[ June 26, 2008: Message edited by: Justin Fox ]


Hey fox and campbell !

lets make it this way what if in the same example






I change this to be

String a = "hell";

// and

String b = new String("heaven");

Now, i think "2copies are maintained" for string b.

Would some one help us on this.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38062
    
  22
Originally posted by ram kumar:
I change this to be

String a = "hell";

// and

String b = new String("heaven");

Now, i think "2copies are maintained" for string b.

Would some one help us on this.
There are in fact two "heaven" Strings. They have existence independent of each other, however.
No, Justin, when you say "new" you tell the JVM to create a 2nd object, which has the same contents as the original. This is usually unnecessary in real life, particularly when String is an immutable class. More details in Joshua Block Effective Java 2/e Santa Clara: Sun Microsystems Press/Addison-Wesley (2008) eg �5 (in the 1st edition �4).
Ronald Schild
Ranch Hand

Joined: Jun 09, 2008
Posts: 117
From the java language specification:

  • Literal strings within the same class (�8) in the same package (�7) represent references to the same String object (�4.3.1).
  • Literal strings within different classes in the same package represent references to the same String object.
  • Literal strings within different classes in different packages likewise represent references to the same String object.
  • Strings computed by constant expressions (�15.28) are computed at compile time and then treated as if they were literals.
  • Strings computed by concatenation at run time are newly created and therefore distinct.


  • This means that:



    References a and b refer to two distinct objects. String a is a literal and is a compile time constant. String b is made at runtime and is a different object. However, reference a does equal b.intern() (bitwise).



    References a and b refer to two distinct objects, even after "c" is appended, because this string is constructed at runtime.



    References a and b refer to the same object. The constant expression "ab" + "c" is computed at compile time and b is interned, meaning it refers to the same object that a refers to.


    Java hobbyist.
    ram kumar
    Ranch Hand

    Joined: May 22, 2008
    Posts: 146
    Originally posted by Campbell Ritchie:
    There are in fact two "heaven" Strings. They have existence independent of each other, however.
    No, Justin, when you say "new" you tell the JVM to create a 2nd object, which has the same contents as the original. This is usually unnecessary in real life, particularly when String is an immutable class. More details in Joshua Block Effective Java 2/e Santa Clara: Sun Microsystems Press/Addison-Wesley (2008) eg �5 (in the 1st edition �4).



    Thats fine !

    As i can see from the discussion,

    it clearly states that using - > new String("string") will create

    2 memory locations.

    So, what do you mean by String.intern();

    I used that on a string literal like

    Raghavan Muthu
    Ranch Hand

    Joined: Apr 20, 2006
    Posts: 3344

    intern() is used to instruct/request the JVM to look for the String reference having the same contents in the String Literal Pool and if there is one it would assign the same reference to this reference variable on which it is invoked.

    Here you go for a nice example -> http://precisejava.com/javaperf/j2se/StringAndStringBuffer.htm


    Everything has got its own deadline including one's EGO!
    [CodeBarn] [Java Concepts-easily] [Corey's articles] [SCJP-SUN] [Servlet Examples] [Java Beginners FAQ] [Sun-Java Tutorials] [Java Coding Guidelines]
    Justin Fox
    Ranch Hand

    Joined: Jan 24, 2006
    Posts: 802
    So unless you use .intern(), there will be multiple copies?

    Thanks,

    Justin
    Ernest Friedman-Hill
    author and iconoclast
    Marshal

    Joined: Jul 08, 2003
    Posts: 24183
        
      34

    Originally posted by Raghavan Muthu:
    it would assign the same reference to this reference variable on which it is invoked.


    Close, but not quite. It doesn't affect the variable you call it through, or the object you call it on. It returns a String with the same contents that is guaranteed to be in the String pool. If the String is already in the pool, it will return that same String. If the String is not, a copy is made in the pool, and a reference to the pooled copy is returned.


    [Jess in Action][AskingGoodQuestions]
    Ernest Friedman-Hill
    author and iconoclast
    Marshal

    Joined: Jul 08, 2003
    Posts: 24183
        
      34

    Originally posted by Justin Fox:
    So unless you use .intern(), there will be multiple copies?

    Thanks,

    Justin


    intern() may make more copies; it will never lead to there being fewer copies.

    Folks, don't call "intern()". Seriously. It has a few rather advanced uses, but at this level you should not be worrying about it.
    Ernest Friedman-Hill
    author and iconoclast
    Marshal

    Joined: Jul 08, 2003
    Posts: 24183
        
      34

    Originally posted by Raghavan Muthu:
    you go for a nice example -> http://precisejava.com/javaperf/j2se/StringAndStringBuffer.htm


    Actually that's not a nice example. There are dozens of flagrant errors and fundamental misunderstandings. You'd do yourself a favor by never visiting that site again. Seriously. Forget everything you read on that page.
    ram kumar
    Ranch Hand

    Joined: May 22, 2008
    Posts: 146
    Originally posted by Ernest Friedman-Hill:


    Actually that's not a nice example. There are dozens of flagrant errors and fundamental misunderstandings. You'd do yourself a favor by never visiting that site again. Seriously. Forget everything you read on that page.



    Thanks Ernest!

    But Would you just tell me a situation that will, intentionally force the use of intern().

    I will try to write the code.

    Will help me what intern() is in a better way!
    Ernest Friedman-Hill
    author and iconoclast
    Marshal

    Joined: Jul 08, 2003
    Posts: 24183
        
      34

    You know what a "Set" is, right? It's a collection of items, not kept in any order, with no duplication. If a Set contains an object X, and you try to add X to the set, nothing will happen; the Set will still just contain one X.

    Anyway, there's a special Set of String objects kept by the JVM. It's called the "string pool". When the JVM loads a class, it loads all the String literals into that Set, and then uses the instance of the literal that's actually in the Set. Since there are never any duplicates in that Set, this ultimately means that all equal String literals in a program refer to the same physical object.

    What "intern()" does -- and this is all it does -- it look to see if a String exists in that special set. If the String does exist in the Set, intern() returns the copy that is in the Set. If the String does not already belong to that Set, intern() adds a copy of it to the Set, and returns that copy.

    The return value of intern() is always a String that's in that special Set.

    Finally, I think you're asking about when it's appropriate to use intern(). I've already said "never", but apparently that's not a good enough answer

    One case where I've used it is in writing language parsers and text processing code. Imagine you were writing a program which had to read a large body of text and build a tree out of it; maybe it's a syntax or grammar tree of some kind. Your program would break the text into individual words. If this is English language text, say, then some words will be used very many times, words like "the", "and", "it", "is", etc. Because each String was read out of a file and created at runtime, each "and" is a different String object. If you have a tree built out of a million words, you can see how there would be very many Strings in the tree that were duplicates, and that duplication could use up a noticeable amount of memory.

    So in this case, the parser might call "intern()" on each String it created, discarding the ones that were read from the file, and keeping instead the copies in the String pool. Now every "and" in the tree would refer to the same physical String object. The whole tree would take up substantially less memory.
    Ronald Schild
    Ranch Hand

    Joined: Jun 09, 2008
    Posts: 117
    Hi Ernest,

    A bit back in this thread you said that intern() will never reduce the amount of copies. Does this go for strings allocated with new?

    Campbell Ritchie
    Sheriff

    Joined: Oct 13, 2005
    Posts: 38062
        
      22
    Originally posted by Ronald Schild:
    Hi Ernest,

    A bit back in this thread you said that intern() will never reduce the amount of copies. Does this go for strings allocated with new?
    Yes. But you have 40000 String objects which are eligible for garbage collection.
    Ernest Friedman-Hill
    author and iconoclast
    Marshal

    Joined: Jul 08, 2003
    Posts: 24183
        
      34

    Originally posted by Campbell Ritchie:
    Yes. But you have 40000 String objects which are eligible for garbage collection.


    That's right. In my word-tree example above, you create the same large number of "and" Strings, but then you get to replace them all with the single copy that intern("and") will return every time, and they'll all be collected.
    Ronald Schild
    Ranch Hand

    Joined: Jun 09, 2008
    Posts: 117
    Thanks for the replies, Campbell & Ernest


    Another small question if that's ok, is it safe to assume that strings not allocated with new are referenced by the string constant pool?



    I know the string objects that a and b referred to remain because the string constant pool references them. But will the object that c referred to be collected?
    Ernest Friedman-Hill
    author and iconoclast
    Marshal

    Joined: Jul 08, 2003
    Posts: 24183
        
      34

    The problem with a simple rule like the one about "new" is that nothing's actually ever that simple!

    Technically, the value of c should be computed by the compiler, not at runtime, and therefore it's actually going to be stored in the string pool too. On the other hand, it's technically not a String literal. I don't believe the SCJP is going to ask you this question!
    Campbell Ritchie
    Sheriff

    Joined: Oct 13, 2005
    Posts: 38062
        
      22
    Last time I tried something like

    String s1 = "Campbell";
    String s2 = "Camp;;
    String s3 = "bell";
    String 24 = s2 + s3;
    System.out.println(s1 == s4);

    it printed "true" so it appears that the compiler will concatenate Strings with the + operator. But it is hardly right to build a rule on that sort of experience.
    Mike Simmons
    Ranch Hand

    Joined: Mar 05, 2008
    Posts: 3003
        
        9
    That code prints false for me - as it should, according to the rules for compile-time constant expressions. It will print true if you make s2 and s3 final though.

    [Ronald]: Another small question if that's ok, is it safe to assume that strings not allocated with new are referenced by the string constant pool?

    No. It's sometimes true, but not always, and the precise rules are complicated. Generally it's best to just not write code that uses == for strings (use equals() instead), and then it won't matter.
    Ronald Schild
    Ranch Hand

    Joined: Jun 09, 2008
    Posts: 117
    Thanks again for the replies

    I know equals() is the way to go to compare string content. I'm just in a search to see what the string constant pool exactly does and when strings are eligible for the GC and when not (even if this won't be asked on the sjcp on this level).

    As you pointed out,



    prints false (Ritchie, are you sure this is what you compiled instead of something like a == "a" + "bc"?). I'll assume that any string referenced by the constant pool is interned, and that d is the above example is not in the string constant pool. Because if it is, I could put line 4 in a loop and I'd have say, 40000 of them referenced by the constant pool (since they're not interned, as line 5 prints false).

    But now the search for proof
    ram kumar
    Ranch Hand

    Joined: May 22, 2008
    Posts: 146
    Originally posted by Ronald Schild:
    Thanks again for the replies

    I know equals() is the way to go to compare string content. I'm just in a search to see what the string constant pool exactly does and when strings are eligible for the GC and when not (even if this won't be asked on the sjcp on this level).

    As you pointed out,



    prints false (Ritchie, are you sure this is what you compiled instead of something like a == "a" + "bc"?). I'll assume that any string referenced by the constant pool is interned, and that d is the above example is not in the string constant pool. Because if it is, I could put line 4 in a loop and I'd have say, 40000 of them referenced by the constant pool (since they're not interned, as line 5 prints false).

    But now the search for proof


    Hey comon you all!

    When ever we start this ,we will keep on digging !

    May be we should nominate this question to JavaOscarAwards(if such exists) as the most suspecious question from java?

    we will do that soon!!!

    while thats good, but finally !

    what do you say !

    Is

    String A = "abc";//constructs one string literal in string constant pool

    String B = new String("ddd"); // watch out am not using same string literal
    abc .

    //constructs one string literal in string constant pool also in the heap that will one memory address refernce to the pool

    AM i RIght?
    Please clarify ?


    Ronald Schild
    Ranch Hand

    Joined: Jun 09, 2008
    Posts: 117
    Originally posted by ram kumar:


    String A = "abc";//constructs one string literal in string constant pool

    String B = new String("ddd"); // watch out am not using same string literal
    abc .

    //constructs one string literal in string constant pool also in the heap that will one memory address refernce to the pool


    Hi Ram,

    According to me, the above code will construct:

    The string object that B refers to may become eligible for garbage collection, the string object that A refers to is referenced by the
    string constant pool.

    Edit: my ascii skills are horrible at best, and it's eligible, not illegible. Pardon me
    [ June 30, 2008: Message edited by: Ronald Schild ]
    Campbell Ritchie
    Sheriff

    Joined: Oct 13, 2005
    Posts: 38062
        
      22
    I am sure I did manage to get something like that to print true, but it might, as Ronald Schild suggests, have been . . . == "Camp" + "bell"

    It was a long time ago, so I have forgotten, sorry.
    Raghavan Muthu
    Ranch Hand

    Joined: Apr 20, 2006
    Posts: 3344

    Mike Simmons has clearly told the fact. Campbell's program should be and is printing false and can be made print true provided the two string reference variables s2 and s3 are final.

    The below code is printing the result 'true'

    Raghavan Muthu
    Ranch Hand

    Joined: Apr 20, 2006
    Posts: 3344

    Originally posted by Ernest Friedman-Hill:


    Close, but not quite. It doesn't affect the variable you call it through, or the object you call it on. It returns a String with the same contents that is guaranteed to be in the String pool. If the String is already in the pool, it will return that same String. If the String is not, a copy is made in the pool, and a reference to the pooled copy is returned.


    Thank you for correcting with the proper explanation EFH.

    Your example with Set is very nice. Thank you so much
    [ July 01, 2008: Message edited by: Raghavan Muthu ]
    Raghavan Muthu
    Ranch Hand

    Joined: Apr 20, 2006
    Posts: 3344

    Originally posted by Ernest Friedman-Hill:


    Actually that's not a nice example. There are dozens of flagrant errors and fundamental misunderstandings. You'd do yourself a favor by never visiting that site again. Seriously. Forget everything you read on that page.


    Is that so? Thank you EFH. It would be so nice if you can just point out a few. As such it looked nice to me
     
    jQuery in Action, 2nd edition
     
    subject: The well known String str = "abc" and String str1 = new String("abc");
     
    Similar Threads
    String handling.
    equals() and ==, doubt
    Behaviour of + in case of String literals
    String literal objects in String pool
    String literal and String object comparison