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
posted
0
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?
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.
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
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.
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
posted
0
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
posted
0
What was the reason for making Strings immutable?
Steven Bell
Ranch Hand
Joined: Dec 29, 2004
Posts: 1071
posted
0
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
posted
0
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
posted
0
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
posted
0
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
posted
0
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
posted
0
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
posted
0
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
posted
0
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.