Open In App

Mutable and Immutable Objects in Java

Last Updated : 09 Jul, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Java is a popular object-oriented programming (OOP) language and it's code design revolves around it's objects and their manipulation. One of the key concepts in this OOP paradigm is the classification of objects into mutable and immutable types. These classifications say whether an object's state can be modified after its creation or not. This is very important concept to understand the behavior and design of Java programs.

Pre-requisite: Object Oriented Programming (OOPs) Concept in Java

Note: In this article, an object's state at a particular instant means the snapshot of all of the values of that object's data members (or fields) at that particular point of time.

This article explains the definition, example, code, comparison, and advantages of Mutable and Immutable Objects in Java.

Mutable Objects

Mutable class objects are those whose state can be modified after initialization. This means the values of their fields can be changed, add or remove elements from the collections they contain, ie generally alter their internal state. Examples of mutable objects are Java's StringBuilder, StringBuffer, & java.util.Date.

In mutable objects, changes to the object's state (data members) do not result in the creation of a new object. Instead, the existing object's values are modified through functions provided by the object's class, such as setters. Mutable objects have both getters and setters functions.

Immutable Objects:

On the other hand, immutable class objects are those whose state cannot be modified after initialization. Once created, the values and state of an immutable object remain fixed throughout its scope. Examples of immutable objects are primitive types like int, long, float, double, as well as classes like String. all legacy classes and wrapper classes are Immutable classes.

Immutable objects, by their nature, do not provide methods/functions to modify their state. Instead, they only offer getters to retrieve their values and no setters function. Any attempt to change an immutable object's state results in the creation of a new object with the modified values.

Mutable & Immutable Class examples

Mutable class:

Mutable class coding:

  • Encapsulate mutable fields: Keep access modifiers of all data fields (or attribute/members) as private and provide modification access through getter and setter functions only.
  • Synchronize access: Use synchronization mechanisms if the object will be accessed by multiple threads to avoid race conditions.
  • If mutable class objects is stored in a collection type, it should be carefully ensured that the collection's contract doesn't allow modification of objects outside of the code's control.
Java
public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String newName) {
        this.name = newName;
    }

    public static void main(String[] args) {
        Person person = new Person("John");
        System.out.println(person.getName());
        person.setName("Doe");
        System.out.println(person.getName());
    }
}

Output
John
Doe


Immutable class code:

  • All mutable data fields should be private and final so that fields once initialized, cannot be directed accessed, modified or iterated.
  • No setter methods in Class to avoid functions that modify the object's state.
  • If immutable class object contains mutable fields (like arrays or collections), return defensive copies to maintain immutability.
  • Make the Final class, (declared as final) so that it can't be extended.
Java
public final class Point {
    private final int x;
    private final int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public static void main(String[] args) {
        Point point = new Point(5, 10);
        System.out.println("X: " + point.getX() + ", Y: " + point.getY());
    }
}

Output
X: 5, Y: 10


Key Differences:

  • Mutable class objects allow changes to their state after initialization, while immutable class objects do not.
  • Mutable class objects provide methods to modify their content, whereas immutable class objects do not allow state modification.
  • Mutable class objects may or may not be thread-safe, while immutable class objects are inherently thread-safe.
  • Creating a new object is required when modifying the state of an immutable class object, while mutable class objects are modified in place.

Here are summary of important differences.

Mutable

Immutable

can change the value of the object after initialization.

cannot change the values of object after initialization

State can be changed

State remains constant after creation

No new objects are formed

Changing the value of the object creates a new object

Provides methods to change object

Does not provide methods to change object value

Supports get() and set() methods

Only supports get() method to retrieve object value

May or may not be thread-safe

Immutable objects are inherently thread-safe

Essentials for creating a mutable class include methods for modifying fields, getters, and setters

Essentials for creating an immutable class include final class, private fields, and final mutable objects

Advantages and Uses of Mutable & Immutable Object

Mutable Objects AdvantagesImmutable Objects Advantages
Flexibility: Mutable class objects allow modification of their state, which is useful for dynamic changes.Thread Safety: Immutable objects can be shared across threads without synchronization since their state cannot change.
Performance: Often perform well since they can be modified directly without creating new objects.Security: Immutable objects are more secure as their state cannot be altered maliciously after creation.
Builder Pattern: Mutable objects are commonly used with the builder pattern, allowing fluent and readable object creation.Simpler State Management: Immutable objects simplify debugging and maintenance because their state does not change unexpectedly.
Caching: Ideal for caching mechanisms as their state does not change, making them easily cacheable.
Memory Management: Easier memory management since they do not require defensive copying.

Next Article

Similar Reads