String s = ...;
s = s.substring(1);
Is this possible? I thought you can't change a String object in Java.
String s = ...;
s = s.substring(1);
Is this possible? I thought you can't change a String object in Java.
String objects are immutable. String references, however, are mutable. Above, s
is a reference.
Here you are creating a new string and assigning it to a pre-used reference. The original string that s referred to is garbage collected. No strings actually changed.
String is Immutable String is the most used immutable class in Java. If new Java developers had to deal with a mutable String they may get very frustrated and overwhelmed by the complexity of the object model and give up on Java not long after starting.
String s = "nothing special";
s.toUppercase();
s.substring(1);
This does not modify the variable s at all. Instead, a new String object is created with all the characters of s changed to upper case. Since the new object is not assigned to anything, it is simply loses all references (as the toUpperCase method has completed) and is eventually garbage collected. On the other hand, you could write it like this:
String s = "nothing special"; s = s.toUppercase(); In this example, s is now in all upper case letters, but it is not the same object as the one that was instantiated in the first line. The new String object that is returned from toUpperCase becomes assigned to s, and the original object loses its last reference and gets garbage collected.
String objects are immutable, meaning that the value of the instance referred to by s
cannot change.
Your code does not mutate the instance.
Rather, it changes the s
reference to refer to a new string instance.
For example:
String a = "1";
String b = a;
a = "2";
After executing this code, b
is still "1"
.
The line b = a
sets b
to refer to the same "1"
instance that a
currently refers to.
When you subsequently write a = "2"
, you are changing the a
variable to refer to a different ("2"
) instance.
However, the original "1"
instance, which b
still refers to, has not changed.
Yes, String
objects are immutable.
The variable s
is a reference to an object, and the reference itself can have the object it points to change -- reassigning the reference does not affect the object it points to.
The String.substring
method is actually returning a new instance of a String
, so the original String
object is left untouched.
The following is a simple example to show that the original String
is not altered by the substring
method::
String s = "Hello!";
s.substring(1);
System.out.println(s); // Prints "Hello!"
The above example will print "Hello!" because the substring
method will return a new String
rather than affect the original one. The original String
cannot be altered because it is immutable.
Compare the above with the following:
String s = "Hello!";
s = s.substring(1);
System.out.println(s); // Prints "ello!"
In this example, the reference to s
is changed to the String
returned by the substring
method, so when the String
associated with s
is printed by `System.out.println", the string that is output will be "ello!"
So:
String foo = "foo";
foo.substring(1);
System.out.println(foo);
//of course..
foo = "aa";
System.out.println(foo);
When you use String s = "abc", you create a String reference to a String object that has the immutable value "abc".
Then, when you say s = s.substring(1);, you assign s to a newly created String object that contains "bc" - but the original object is unchanged.
This is a common cause of errors, because if you did not assign the value, you may get unexpected results.
Many novice Java developers will use such methods like trim(), not realizing that trim() doesn't affect the String.
s.trim() <-- Does nothing to s, returns a trimmed string - this is a bug.
s = s.trim() <-- Stores the trimmed string - this is correct.
Test it:
String s = "Test";
String j = s;
s = s.substring(1);
s
is now T
and j
is still Test
.