The code you posted above does not actually mutate any lines, although it seems like it is. The reason is that this line does not mutate the line:
string = string + "bcd";
Instead, it means:
- Build a new line whose value is
string + "bcd" . - Change which string string refers to to refer to this new string.
In other words, the particular string string objects themselves were not changed, but the references to those strings were indeed changed. Invariance in Java usually means that objects cannot be modified, not references to these objects.
An important detail that confuses many new Java programmers is that the above line is often written as
string += "bcd";
which looks even stronger, as if it combines bcd at the end of the line and thereby mutates it, even if it is equivalent to the above code and therefore does not cause any changes to the actual string object again, it works by creating a new string object and changing to which the link belongs to the object.)
To see what is happening here, you are actually modifying the link, not the line to which it refers, you can try rewriting the code to make string final , which prevents you from changing which link object. If you do this, you will find that the code no longer compiles. For instance:
class toString{ public static void main(String[] args){ final String string = "abc"; string = string + "bcd";
One final note, another common reason for grief for new Java programmers when using string is that string has methods that seem to modify the string, but don't actually do it. For example, this code does not work correctly:
String s = "HELLO, WORLD!"; s.toLowerCase();
Here the call to s.toLowerCase() does not actually convert the characters of the string to lowercase, but instead creates a new string with the characters set to lowercase. If you then rewrite the code as
String s = "HELLO, WORLD!"; s = s.toLowerCase(); // Legal and correct System.out.println(s); // Prints hello, world!
Then the code will behave correctly. Again, the key detail here is that assigning s does not change any particular string object, but simply adjusts what the s object refers to.
Hope this helps!