0

Since string is immutable I have to write as follows to remove all non-alphanemeric from the str.

void test(String str) {
    str = str.replaceAll("[^a-zA-Z0-9\\s]", "").toLowerCase();
    System.out.println("\n" +str);
    }

What I couldn't understand is that how come it works by re-assigning to str?

Since String is immutable, I understand that if I assign it to a new String newString, they are pointing out two different objects, str and newString. That it, original string is pointing to str and modified string is pointing ot newStr which have two different immutable Strings. This is ok for me.

void test(String str) {
            String newStr = str.replaceAll("[^a-zA-Z0-9\\s]", "").toLowerCase();
    System.out.println("\n" +newStr);
    }

But how come it works by reassigning to the same str object? Based on my understanding, it shouldn't be working since immutable str cannot me modified, so the result of the modified str cannot be stored in immutable str.

void test(String str) {
      // this shouldn't be working based on my understanding. But it works. Why?
    str = str.replaceAll("[^a-zA-Z0-9\\s]", "").toLowerCase();
    System.out.println("\n" +str);
    }

As you've seen the following image, string1 and string2 are pointing to the same String object in the heap. Could you clarify how this works internally?

user2761895
  • 1,431
  • 4
  • 22
  • 38

3 Answers3

2

You aren't assigning to the same str object.

Take a look at the replaceAll etc methods and you will see that they return String, that is a new String object that the replaceAll method has created.

So str=str.replaceAll() takes your String reference from str, calls replaceAll() in that String. replaceAll processes this and then returns a new String object with the results of that processing. You then assign that back into the original reference.

Tim B
  • 40,716
  • 16
  • 83
  • 128
2

You need to understand references: str is a reference to a certain area in your memory. What's happening is, the Java runtime creates a new memory area with the string where all the characters are removed and then "points" str to the new memory area.

This is not the same as modifying the memory area the str already points to.

"Immutability" means that the memory area a variable points to can not be modified. The content is fixed. To "modify" it, memory must be copied, modified and then be reassigned.

"Mutable" objects can modify data in memory without copying the old data to a new memory area.


By the way, in our example, the string is even copied twice!

First time, this copyies the string:

replaceAll("[^a-zA-Z0-9\\s]", "")

Then another copy is created by

toLowerCase()

which is then finally assigned to your variable.

Your code is thus equal to the following:

void test(String str)
{
    String str1 = str.replaceAll("[^a-zA-Z0-9\\s]", "");
    String str2 = str1.toLowerCase();
    str = str2;

    System.out.println("\n" +str);
}
Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139
0

You need to understand that in Java, variables are not objects; variables are references to objects.

So, str is not a String object, it is a reference to a String object. "Immutable" means that the content of the object that the variable is referring to cannot be changed; it does not mean that the variable itself cannot be changed to refer to a different object.

You're making str point to a different String object; namely, the new String object that str.replaceAll returns.

Jesper
  • 202,709
  • 46
  • 318
  • 350