12

I'm trying to understand exactly how Java strings are immutable. I get that this should probably be an easy concept, but after reading several online web pages I still don't quite understand.

I don't understand how Java Strings are "immutable". I currently have the following code:

public static void main(String[] args) {

  String name = "Jacob Perkins";

  System.out.println( name );

  name = name + "!";

  System.out.println( name );

}

My output is the following:

Jacob Perkins
Jacob Perkins!

Why is this happening if a string is supposed to be immutable? Why am I able to re-assign a value to the string?

nullptr
  • 2,244
  • 1
  • 15
  • 22
user2301187
  • 157
  • 1
  • 7
  • `String` *variables* are not immutable (because they vary!) You have created a new string and assigned its reference to the variable `name`. – dlev May 08 '13 at 04:11
  • I still don't understand. Why do I see the term 'immutable' with Java strings? – user2301187 May 08 '13 at 04:13
  • @user2301187: Two variables can point to the same string object. If strings were mutable, one variable's changes to the string could be seen through the other variable's reference. Since they are not, every variable knows that the string it points to can't 'change while it is not looking'. This is done because mutable strings would be scary and add a lot of complexity, e.g. you would have to remember to make a copy of a string whenever you wanted a copy of it that wouldn't change, or strange things would happen later, potentially insecure things too! – Patashu May 08 '13 at 04:15
  • but it looks as if `name = name + "!"` is changing the value of the original name variable. I'm still not understanding. – user2301187 May 08 '13 at 04:19
  • @user2301187 I have posted an answer explaining it – Patashu May 08 '13 at 04:23
  • What this means is that strings themselves cannot be changed. When you use the '+' operator, you actually create a new String with the part after the '+' already added onto it, so you never modify your current String (hence "immutable"), you actually create a new one. – Martin Tuskevicius May 08 '13 at 04:32

7 Answers7

35

Let an image explain this for you:

String example

On the left side, you have the variable, which in fact is a reference.

  1. String name = "Jacob Perkins;" The String "Jacob Perkins" is created, and name points to it.
  2. name = name + "!"; A new String "Jakob Perkins!" is created, and the reference now points to the new String. The old one, however, remains unchanged, because String is immutable.
Uooo
  • 6,204
  • 8
  • 36
  • 63
5

The string itself, once created, can never be changed. What your code sample does is to replace the string in name with a new string that was constructed from the previous contents of name, and an exclamation point. (The original contents of name, which are no longer referenced by any variable, will eventually be reaped by the garbage collector.)

If you were to examine the compiled code (or step through it with a debugger), you would discover that your name + "!" expression had been compiled into the creation of a StringBuilder object and a few operations on that object.

That is, the strings are immutable, but the variable name is not. Its value changes, to point to different strings. The strings themselves never change.

Edward Falk
  • 9,991
  • 11
  • 77
  • 112
1

The String objects are immutable only the variable reference changes.

In your example the "Jacob Perkins" object still exists and a new object "Jacob Perkins!" gets created.

The name variable points to the new object.

Bhushan Bhangale
  • 10,921
  • 5
  • 43
  • 71
1

Maybe this will help you to understand.

Let's say you have a class Point (java.awt.Point). Let's say you have one instance p:

Point p = new Point(0,0);

Then you make create a new variable y referencing the same object p as:

Point y = p;

If you change the value of p, you also change y. Because the class Point is mutable.

p.setLocation(1,1);

It makes y reference the location 1,1 as well.

Using the String class it does not happen.

String a = "123";
String b = a;

If you make a = a + "4"; The new value of a will be "1234" but b is still "123";

The object they were referencing didn't change, it's just that a is pointing to another object now.

pablosaraiva
  • 2,343
  • 1
  • 27
  • 38
0

What actually happens is there are 3 String objects created. "Jacob Perkins", "!" and "Jacob Perkins!". You didn't really modify the "Jacob Perkins" instance. You just changed the reference of the name variable, from "Jacob Perkins" instance to "Jacob Perkins!".

renz
  • 1,072
  • 3
  • 11
  • 21
  • I don't understand what you mean by "changing the reference of the name variable". – user2301187 May 08 '13 at 04:16
  • In the first println(), the name variable is pointing to the "Jacob Perkins" String object. That object didn't really change, since strings are immutable. Instead, two other new String objects are created, "!" and "Jacob Perkins!". And then the name variable is pointed to the "Jacob Perkins!". You actually created 3 String objects, none of which was muted. – renz May 08 '13 at 04:22
0
String name = "Jacob Perkins";

String name2 = name + "!";
name.substring(5); // or wather syntax is

Those do not change variable name

Siddharth
  • 9,349
  • 16
  • 86
  • 148
timoras
  • 98
  • 11
0

In Java there are references and there are values.

When you say

String foo = "John Smith";

foo is a variable, holding a reference. The reference points to the object, or value, containing "John Smith".

The reference held by the variable is mutable. I can do this:

foo = "Jack Smith";

And I have mutated the reference. However if I write code like this:

String foo = "John Smith";
String bar = foo; //bar's reference is a copy of foo's reference - the same value
foo = "Jack Smith";
System.out.println(bar); //prints John Smith

We see that even though we changed foo, bar has not changed. Why? Simply, when we wrote foo = "Jack Smith"; we made foo point to a new String. We didn't reach through foo and modify the string, since No method in Java mutates, or can mutate a String. Instead, a new String is returned, and the variable is made to point to the new, also immutable String. This way, the object a String variable 'points' to can never be modified by anything but through that variable. This is an important property of the Java language that it guarantees.

Patashu
  • 21,443
  • 3
  • 45
  • 53