Understanding Mutability in Java

Murat
5 min readDec 26, 2022

--

Are you tired of the boring, dry explanations of mutable and immutable objects? Well, fear not! In this blog, we’ll take a more lighthearted approach to understanding these concepts.

First, let’s start with the basics. In Java, an object is considered immutable if its state cannot be modified once it is created. In other words, you can’t change the innards of an immutable object no matter how hard you try. It’s like trying to change the laws of physics — it just ain’t gonna happen.

Now, you might be wondering, “Why on earth would I want to use immutable objects if they can’t be changed?” Good question! It turns out that immutable objects have a few key benefits.

Imagine you’ve got a bunch of threads running around, all trying to access the same object. If that object is mutable, it’s like trying to have a conversation with a group of people who are all talking at the same time. It’s chaotic and nobody can understand what’s going on. But if the object is immutable, it’s like having a conversation with a group of people who are all talking one at a time. Everything is much clearer and easier to follow.

Now, we know what you’re thinking: “But wait, doesn’t that mean I can never change the state of an immutable object?” Well, not exactly. You see, even though the object itself is immutable, it can still contain references to mutable objects. It’s like having a group of people who all have to raise their hand before they speak. The group itself is immutable, but the individuals within it can still change their minds and raise their hands whenever they want.

In other words, Immutable objects are thread-safe. Since their state can’t be modified, there’s no need to synchronize access to them. This makes them particularly useful in concurrent environments, where multiple threads may be accessing the same object.

On the other hand, a mutable object is like a chameleon — it can change its state to fit whatever situation it finds itself in. This means that it is possible to change the object’s state in-place, without creating a new object.

Mutable objects have a few key advantages in Java programming.

Flexibility: Mutable objects can be modified at any time, which can be useful in situations where the state of the object needs to change frequently. This can be especially useful in situations where the state of the object depends on user input or other external factors.

Ease of use: In some cases, mutable objects can be easier to work with than immutable objects. For example, it may be simpler to modify an existing mutable object rather than creating a new immutable object each time the state needs to change.

Performance: In some cases, mutable objects can be more efficient than immutable objects. For example, modifying an existing mutable object may be faster than creating a new immutable object, particularly if the object is large or complex.

Mutable and Immutable Objects in Java

Let’s continue with an example to understand immutable object in java.

Here is an example of an immutable object in Java:

public final class ImmutableObject {
private final int value;

public ImmutableObject(int value) {
this.value = value;
}

public int getValue() {
return value;
}
}

In this example, the ImmutableObject class has a single field, value, which is marked as final. This means that the value of the field cannot be changed after the object is created. The class also does not have any methods that allow the value to be modified, so the object's state remains unchanged.

Here is an example of how to use an immutable object in Java:

ImmutableObject obj = new ImmutableObject(10);
System.out.println(obj.getValue()); // Outputs: 10

// The following line will cause a compilation error, because the value field is marked as final
obj.value = 20;

// To change the value of the object, we must create a new instance with the new value
obj = new ImmutableObject(20);
System.out.println(obj.getValue()); // Outputs: 20

In java String, all legacy classes, Wrapper class (Integer, Byte, Long, Float, Double, Character, Boolean and Short) etc. are an immutable.

As you can see in the picture below if you assign new value to immutable primitive wrapper class ,memory will create a new object and not modify the old.

Immutable Objects Memory Representation by pythonsimplified

If we understand the example of immutable object, Let’s create mutable object!

public class MutableObject {
private int value;

public MutableObject(int value) {
this.value = value;
}

public int getValue() {
return value;
}

public void setValue(int value) {
this.value = value;
}
}

In this example, the MutableObject class has a single field, value, which can be accessed and modified using the getValue and setValue methods. This means that the state of a MutableObject can be changed after it is created, as shown in the following example:

MutableObject obj = new MutableObject(10);
System.out.println(obj.getValue()); // Outputs: 10

obj.setValue(20);
System.out.println(obj.getValue()); // Outputs: 20

As you can see, the value of the MutableObject can be changed by calling the setValue method, which allows the object's state to be modified in-place. This is an example of a mutable object in Java.

There are several built-in mutable objects in Java that you can use in your programs like StringBuilder, HashMap, java.util.Date etc.

Conclusion

So, which type of object should you use? It really depends on your needs. If you need an object that can change its state on the fly, a mutable object might be the way to go. But if you need a little more stability in your life an immutable object might be the better choice.

Just remember: with great power comes great responsibility. Use mutable and immutable objects wisely, or you might end up with a codebase that’s as chaotic as a chameleon trying to blend in with a rainbow.

--

--