• Post Reply Bookmark Topic Watch Topic
  • New Topic

Questions regarding the article "String Literally" written by Corey McGlone  RSS feed

 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dear ranchers,

I have few problems understanding the article The SCJP Tip Line Strings, Literally written by Corey McGlone. As inetrn(), gc of String is not covered in SCJP, so I am posting it here instead of SCJP forum.



Quote supporting the above code...

When a .java file is compiled into a .class file, any String literals are noted in a special way, just as all constants are. When a class is loaded (note that loading happens prior to initialization), the JVM goes through the code for the class and looks for String literals. When it finds one, it checks to see if an equivalent String is already referenced from the heap. If not, it creates a String instance on the heap and stores a reference to that object in the constant table. Once a reference is made to that String object, any references to that String literal throughout your program are simply replaced with the reference to the object referenced from the String Literal Pool.


I am not able to understand the line which I have put in bold.



Quote as per the above code...

In this case, we actually end up with a slightly different behavior because of the keyword "new." In such a case, references to the two String literals are still put into the constant table (the String Literal Pool), but, when you come to the keyword "new," the JVM is obliged to create a new String object at run-time, rather than using the one from the constant table.


Here before the execution of new... how constant table pool maintains the references of two string literals as there is only one string literal "someString". Why he said "references to the two String literals are still put into the constant table" , it means in first case also constant table maintains references of two objects. I am totally confused now.

One more thing....

It is mentioned in the article that String literal constant table maintains a references of String object. Is my understanding correct?.... that the pool maintains a key/value kind of thing. key is actual string content and value is the reference of string object and each key has a single value.

Thanks for looking at my queries

Regards

Naseem
[ July 25, 2006: Message edited by: Naseem Khan ]
 
Campbell Ritchie
Marshal
Posts: 56541
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Common beginner's problem. Strings are immutable. Go through the String class API and count how many methods change things and have a void return type. There oughtn't to be any.

So you can't change a String object; when you think you are changing it, you aren't, you are producing a new String object.

That means when you have Strings in your app like:-

    "Naseem Khan"
    "Naseem " + "Khan"
    String.format("%s %s", "Naseem", "Khan"); [I think-I have never tried this one], or
    "Na" + "seem Khan",

the JVM puts them all into one single String objct on the heap, and all the different names (identifiers) you use for all those Strings all point to the same object. Imagine you wrote

Using the new operator however, tells the JVM to produce a different object.So shouldThat is why you have overridden equals() methods (String has one that works, StringBuilder hasn't). You can quite easily tell the difference. Set up a program which creates a set of String objects as above. And for all the combinations, put in this sort of print statement:-Print out all the combinations, see how you created the String, and whether == and equals print out "true" or "false."

Remember the code I have quoted only works in Java 5.

[ July 26, 2006: Message edited by: Campbell Ritchie ]

[Andrew: Changed formatting for readability and to reduce chances of horizontal scrolling being required]
[ July 26, 2006: Message edited by: Andrew Monkhouse ]
 
Naseem Khan
Ranch Hand
Posts: 809
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the reply. Well I have not asked about the immutability of the Strings. I know they are immutable. My questions are related to that article which I have posted. Could you please explain the quote which I have put in bold from the article mnetioned.

Please help

Thanks

Naseem
[ July 26, 2006: Message edited by: Naseem Khan ]
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, that's basically correct. But the key and value don't need to be different interpretations of the data, as you suggest; they can both be the same. You have a String, you want to look up the "canonical" version. So you compare to all the keys, and when one's equals() method returns true, you use that one.

It's like using a HashMap where each value is its own key. In fact, that's what a HashSet is -- that class is just a thin layer over HashMap. That should tell you that this kind of thing is generally useful.
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Posts: 12156
256
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
    String.format("%s %s", "Naseem", "Khan"); [I think-I have never tried this one]
I suspect you are wrong on this one - I may try looking at the bytecode to confirm this later if I have time, but I believe that there should be three strings here:"%s %s"
"Naseem"
"Khan"Unless the compiler is doing some major optimizations (which it shouldnt be doing), the String.format() method wont be evaluated until runtime, so it will result in a new String being created.

Regards, Andrew
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Posts: 12156
256
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK, tested and confirmed what I was suggesting (actually tested as I was typing the above, but didnt feel like re-writing the above).

For the code:We get the output:And that matches with what I see in the compiled bytecode (partial dump only):So my variables "one", "two", and "three" are all referencing the same String in the String Literal Pool (as shown by bytecode lines 0+2, 3+5, and 6+8 where the same string literal (#2) is stored in various locations.

However at line 9 we can see we are referencing a different String Literal (#3), and again at line 17 we can see the String "Naseem" is a different String Literal (#5) and at line 22 we can see that "Khan" is yet another String literal (#6).

The result of invoking the String.format() method in line 25 is then stored in variable 4 in line 28.

Regards, Andrew

[Andrew: edited to disable smilies]
[ July 26, 2006: Message edited by: Andrew Monkhouse ]
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Posts: 12156
256
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Naseem -

Is this helping at all, or would you like us to try explaining in a different way?

Regards, Andrew
 
Campbell Ritchie
Marshal
Posts: 56541
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I ought to have tried the String.format thing before posting, shouldn't I?
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!