wood burning stoves 2.0*
The moose likes Beginning Java and the fly likes Strings are immutrable? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Strings are immutrable?" Watch "Strings are immutrable?" New topic
Author

Strings are immutrable?

Kedar Dravid
Ranch Hand

Joined: May 28, 2004
Posts: 333
According to the Java API,
Strings are immutable.
How can this statement be explained with the help of an example?
For example, the following code fragment is perfectly valid.
String str1="XD";
String str2="DF";
str1=str2;
str1="KL";
str2="LI";

In this case, aren't we changing the reference values of the String objects?
So, in what way are they immutable?
Ken Loh
Ranch Hand

Joined: Feb 16, 2005
Posts: 190


Originally posted by Kedar Dravid:
According to the Java API,
Strings are immutable.
How can this statement be explained with the help of an example?
For example, the following code fragment is perfectly valid.
String str1="XD";
String str2="DF";
str1=str2;
str1="KL";
str2="LI";

In this case, aren't we changing the reference values of the String objects?
So, in what way are they immutable?

[ April 14, 2005: Message edited by: Ken Loh ]
Joe Ess
Bartender

Joined: Oct 29, 2001
Posts: 8971
    
    9

You are changing the reference. Not the object's value. In the following:
String str1="XD";
String str2="DF";
str1=str2;
You did not change the value of the object "XD". You changed a reference "XD" to refer to "DF". Where this really comes into play is when you start combining and parsing strings. For example:
String str1="XD";
String str2="DF";
str1=str1+str2;
The object that str1 points to is a new object which has the value "XDDF". str2 still points to "DF" and the string object "XD" is waiting around for garbage collection.


[How To Ask Questions On JavaRanch]
Jayesh Lalwani
Ranch Hand

Joined: Nov 05, 2004
Posts: 502
Yes you can have a String variable reference another String object, but you cannot change the String object itself. Let me illustrate with a code example



The above code will output


Initially, at line 3, one and two are 2 seperate reference that point to the same String object. However, at line 4 two+" three" generates a new String object and assigns it to two. the first String object that one points to doesn't change.

The reference is mutable but the object that the reference points to is immutable.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

A variable is a reference or pointer to an object; it's not the object itself. String objects are immutable, but variables that point to Strings can be changed to point to a different String, just like any other variables. This might help you to understand.


[Jess in Action][AskingGoodQuestions]
Andrew Eccleston
Ranch Hand

Joined: Jul 07, 2004
Posts: 140
First, try reading Javaranch's Campfire Story on varuables if you haven't already.

When we say that String objects are immutable, we mean the actual object that your variable is referencing. When you assign a new value to a String variable, as you did above, a second obect is created in memory with the new value. Then, a reference to the new object is placed in your variable. The old object is then left in memory with no reference.

Does this help at all?


The statement below is true.<br />-------------------------------<br />The statement above is false.
kiennjal shah
Ranch Hand

Joined: Jun 17, 2004
Posts: 31
Consider this:

String a = "Hello";
String b = "World";
String c = b;
System.out.println("String a is" + a);
System.out.println("String b is" + b);
System.out.println("String c is" + c);
System.out.println("String ab is" + a+b);
System.out.println("New" + b);

String b = "something else";

System.out.println("String b now is" + b);
System.out.println("String c now is" + c);

Output:
------------------------------------------------
String a is Hello
String b is World
String c is World
String ab is Hello World
New World
String b now is something else
String c now is World
---------------------------------------------

Consider a pool of strings, what we mean by "strings are immutable" is that once I say a="Hello", in the string pool is created a string object with a certain value and reference. now variable a actually holds the reference. For strings, if I say: a= a+"world", it will actually abandon the string "hello" and create A NEW string object with a value "Hello World" and variable a will now refer to it, the string "hello" is now lost in the pool and cannot be recovered (unless u had assigned it to another variable before changing variable a to point to another String.

However, if you use stringBuffer, u can preserve the values as well as modify them.

Hope this helps.

In case I am wrong anywhere please feel free to correct me.

Thanks

-Kiennjal
Savio Fernandes
Greenhorn

Joined: Apr 14, 2005
Posts: 16
What was the reason for making Strings immutable?
Steven Bell
Ranch Hand

Joined: Dec 29, 2004
Posts: 1071
Thread safety and possible performance optimizations would be two I can think of. I'm sure there are more.

Of course it is possible to alter a String at runtime through reflection, but that's cheating a bit.
Savio Fernandes
Greenhorn

Joined: Apr 14, 2005
Posts: 16
I don't understand how Strings being immutable help with thread safety. Can you explain further.
Also, since new Strings are created for every time that I declare a String, how does it help Performance? Wouldn't it decrease Performance since the GC would have to do a lot more work collecting unused Strings? Isnt that why its usually advised to use StringBuffer rather than String to improve performance?
Steven Bell
Ranch Hand

Joined: Dec 29, 2004
Posts: 1071
As far as thread saftey goes, you never have to syncronize to get the value from an immutable class. It can't change in the middle of a read or during some operation that relies on it's value.

As far as performance, it depends. A compiler can better optimize a variable if it knows the value cannot change. If you need the performance of creating large numbers of Strings by modification you can use a StringBuffer.
Steve Kritzler
Greenhorn

Joined: Apr 14, 2005
Posts: 9
Hi there, I'm still a little confused about a part of this. Consider:

String s1 = "hello";
String s2 = "hello";
s1.toUpperCase();
if (s1 == s2)
System.out.println("== match");
if (s1.equals(s2))
System.out.println("equals() match");

Running this prints out both "match" messages.

The call on line 3 does not modify the original string (which remains in the literal string pool), however it creates a new string in the pool and updates s1 with a reference to that new string.

So, if s2 is still referencing the object with "hello", and s1 is referencing object with "HELLO", how is it that both tests are satisfied???
[ April 22, 2005: Message edited by: Steve K. ]
David Harkness
Ranch Hand

Joined: Aug 07, 2003
Posts: 1646
Originally posted by Steve K.:
s1.toUpperCase();
...
The call on line 3 does not modify the original string (which remains in the literal string pool), however it creates a new string in the pool and updates s1 with a reference to that new string.
It creates a new String, yes, but the reference to it returned by toUpperCase() is ignored. Try this:
Steven Bell
Ranch Hand

Joined: Dec 29, 2004
Posts: 1071
Originally posted by Steve K.:

The call on line 3 does not modify the original string (which remains in the literal string pool),

Correct

however it creates a new string

Yes

in the pool

No, on the heap.

and updates s1 with a reference to that new string.

This is where you really go wrong. The s1 reference is no 'updated' to the new String. You can only change a reference with and assignment operator '='. In this case the newly created String is not assigned to anything and is lost, leaving it available for garbage collection.
Steve Kritzler
Greenhorn

Joined: Apr 14, 2005
Posts: 9
Awesome, thanks a lot guys...

One small follow-up...I understand the correction where the new string is created on the heap, however isn't a copy also in the literal string pool?

This would be the case if you were explicitly calling the String constructor (right??), so if the call to toUpperCase() returns a reference to a new String object (with a unique value) isn't a copy placed in the pool?

Thanks again for your help...
[ April 22, 2005: Message edited by: Steve K. ]
Steven Bell
Ranch Hand

Joined: Dec 29, 2004
Posts: 1071
No, the 'pool' is a collection of references to 'literal Strings'. Strings generated during runtime are not added to that collection.

At least this is my understanding, anybody correct me if I'm wrong.
 
 
subject: Strings are immutrable?