• Post Reply Bookmark Topic Watch Topic
  • New Topic

Difference between String Literal and String Object  RSS feed

 
Rajarsi Ghosh
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi

Can any body give me the difference between the String Literals and String Objects and how the JVM implements both.

I came across the following piece of code.
public class Stringcomparison
{
public static void main(String args[]) {
String ss1=new String("Rajarsi");
String ss2=new String("Rajarsi");
String s1="Rajarsi";
String s2="Rajarsi";
System.out.println(" == comparison for StringObjects: "+(ss1==ss2));
System.out.println(" == comparison for StringLiterals: "+(s1==s2));
System.out.println(" equals( ) comparison for StringObjects:"+(ss1.equals(ss2)));
System.out.println(" equals( ) comparison for StringLiterals:"+(s1.equals(s2)));
}
}
===================================
The output is as following:

== comparison for StringObjects: false
== comparison for StringLiterals: true
equals( ) comparison for StringObjects:true
equals( ) comparison for StringLiterals:true
=============================================
 
Campbell Ritchie
Marshal
Posts: 56570
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So, what happened? That should tell you the difference between
"Rajarsi" and new String("Rajarsi").
 
Rajarsi Ghosh
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually i want the difference between "Rajarsi" and new String("Rajarsi") and how the JVM handles the two.
 
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
There's no difference in how they're handled, in that they both represent instances of java.lang.String. The explicit constructor is making a copy of a String that already exists; that's never necessary, and in fact, if you ever see that in real code you know it was written by someone who doesn't know much about Java. The String objects representing the literal are created when a class is loaded and initialized.
 
Merrill Higginson
Ranch Hand
Posts: 4864
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
All strings are String objects. In your example, both statements:

String ss1=new String("Rajarsi");
and
String s1="Rajarsi";

are assigning a variable to a String object.

Strings are handled a little differntly by the compiler than other objects. Because Strings are widely used and to improve efficiency, the compiler creates a "pool" of String objects that gets shared.

The way this works is that if in one process, I specify String s="xyz" and in another process in the same JVM, someone specifies String q="xyz" the compiler will recognize that there's already an instance of String that contains the same value and will reuse it. Since the String object is immutable (cannot be changed once it's created) the compiler can get away with it.

The difference here is that when you specify new String("xyz"), you are telling the compiler that you want a new instance of String created regardless of whether one with the same value already exists or not. Furthermore, you're telling the compiler that this String object will not participate in the pool, and cannot be reassigned somewhere else.

Most of the time, you don't care if your string is from the pool or not, so just writing String x="xyz" is fine. In fact, it's preferred as being more efficient use of the compiler.

However, once in a while you do care. An example would be in a loop when you're comparing string variables that start out with the same value, but one of them may change along the way. In this case, it's important that at the start of the loop, you write

saveValue = new String(value);
rather than
saveValue = value;

If you write the latter, both saveValue and value will always refer to the same instance of String, and will both change together. If you write the former, you are making sure that the variable saveValue refers to a difference instance than value does.
[ August 06, 2006: Message edited by: Merrill Higginson ]
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Merrill Higginson:

However, once in a while you do care. An example would be in a loop when you're comparing string variables that start out with the same value, but one of them may change along the way. In this case, it's important that at the start of the loop, you write

saveValue = new String(value);
rather than
saveValue = value;

If you write the latter, both saveValue and value will always refer to the same instance of String, and will both change together. If you write the former, you are making sure that the variable saveValue refers to a difference instance than value does.

[ August 06, 2006: Message edited by: Merrill Higginson ]

I'm not sure I get what you're trying to say here. What do you mean by changing the String. Per my understaning the first way has no advantasge since Strings are immutable.
 
Matt Harrah
Ranch Hand
Posts: 54
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can find more information in the Javadocs under java.lang.String and the intern() method.
 
Merrill Higginson
Ranch Hand
Posts: 4864
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When I speak of "change" in the above post, I'm speaking of the variables changing (referring to new instances of String) not the strings themselves changing.

Here's an example of what I'm talking about:



If I substitute
saveValue = value;
for
saveValue = new String(value);

The loop will not end until the last row is read from the result set regardless of whether "value" changes or not. This is because both saveValue and value will be pointing to the same instance of String and the same location in memory. By writing new String(value), I have made sure that both variables are independent of each other.

The point I'm trying to make here is that there are legitimate uses of the String constructor, and that not all Strings use the pool of String literals.
[ August 07, 2006: Message edited by: Merrill Higginson ]
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Merrill Higginson:
When I speak of "change" in the above post, I'm speaking of the variables changing (referring to new instances of String) not the strings themselves changing.

Here's an example of what I'm talking about:



If I substitute
saveValue = value;
for
saveValue = new String(value);

The loop will not end until the last row is read from the result set regardless of whether "value" changes or not. This is because both saveValue and value will be pointing to the same instance of String and the same location in memory. By writing new String(value), I have made sure that both variables are independent of each other.

The point I'm trying to make here is that there are legitimate uses of the String constructor, and that not all Strings use the pool of String literals.

[ August 07, 2006: Message edited by: Merrill Higginson ]

I still don't get it. The loop should end as soon as "value" changes. Just because they were both referring to the same String at one point doesn't mean that when one reference changes they both will.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Merrill Higginson:
If I substitute
saveValue = value;
for
saveValue = new String(value);

The loop will not end until the last row is read from the result set regardless of whether "value" changes or not. This is because both saveValue and value will be pointing to the same instance of String and the same location in memory. By writing new String(value), I have made sure that both variables are independent of each other.


That's not true. Try it - both ways work exactly the same way. There only would be a difference if you compared the strings using == instead of equals() - then the loop would terminate immediately using the constructor call.

More specifically, you seem to thing that

value = rs.getString(1);

might be able to change the value of saveValue. It doesn't - the statement simply changes what string the value reference points to, it doesn't have any effect on the saveValue reference.


The point I'm trying to make here is that there are legitimate uses of the String constructor


Perhaps there are, although I'm not aware of one. The above definitely isn't a legitimate use, sorry.
 
Merrill Higginson
Ranch Hand
Posts: 4864
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're right. It only makes a difference if value refers to a mutable object. Guess I was being overly cautious after having made this mistake with a mutable object.
 
Kino Lobo
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
System.out.println(" == comparison for StringObjects: "+(ss1==ss2));

The result is false 'cause you comparing two reference variables, each holding distinct String objects.
I mean, the ss1's value is just the location of the String object at the memory (a pointer, but i didn't say that ).

 
Don't get me started about those stupid light bulbs.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!