6
String s = ...;

s = s.substring(1);

Is this possible? I thought you can't change a String object in Java.

Brandon
  • 109
  • 2
  • 3
  • 1
    You would be correct if only `s.substring(1)` would change the string in `s`. But you are assigning a new string to `s`. – Felix Kling Aug 03 '10 at 15:38
  • 1
    You're just changing the reference s, not the original String itself. A minor style point - it's often better to create a new, descriptively named local variable rather than re-using variables like this. – mikera Aug 03 '10 at 15:41
  • 6
    Don't confuse the objects with the references. Objects may be mutable or immutable. References may be `final` or not. Making a reference `final` does not make the object immutable. Immutable objects can be referred to by references which doesn't have to be `final`. – polygenelubricants Aug 03 '10 at 15:54
  • Brandon You should first understand what a reference is and what mutability is. – Ajay Bhojak Aug 02 '13 at 08:40

8 Answers8

25

String objects are immutable. String references, however, are mutable. Above, s is a reference.

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
  • 1
    +1 short and correct. The initial value of s is still there, unchanged and possibly now unreferenced, in memory - waiting to get GC'd. However, the reference s now points to a new, likewise immutable object, created by the substring method. –  Aug 03 '10 at 15:39
  • 3
    Dang, I wish I had seen this Q before you to get myself a bunch of easy rep. :) +1 – iandisme Aug 03 '10 at 15:41
6

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.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
4

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!"

coobird
  • 159,216
  • 35
  • 211
  • 226
2

//Create a reference s to String "Hello"

String s = "Hello";

//Now print subString of string referred by s

System.out.println(s.subString(1));

//Now print String referred by s

System.out.println(s);

The above code snippet would first print H and then on second line it will print Hello. Now Why did it first print H? : Thing is subString() method returns a String *without changing the the string referred by reference s*. s is still referring to "Hello". Now when you try to print s it will print the string to which s is referring. in This way String "Hello" is immuatble. you are just able to use it to produce another string but you can not mutate it.

When use statement s = s.subString(1); What you are doing is that s is now referring to a subString() of "Hello" but "Hello" itself is still not modified.

Ajay Bhojak
  • 1,161
  • 9
  • 17
2

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.

Kurt
  • 4,477
  • 2
  • 26
  • 34
0

So:

String foo = "foo";
foo.substring(1);
System.out.println(foo);

//of course..
foo = "aa";
System.out.println(foo);
Enno Shioji
  • 26,542
  • 13
  • 70
  • 109
0

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.

MetroidFan2002
  • 29,217
  • 16
  • 62
  • 80
0

Test it:

String s = "Test";
String j = s;

s = s.substring(1);

s is now T and j is still Test.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143