AlgoDaily - Understanding Mutable vs. Immutable Objects

9 min read Original article ↗

Read at your own pace. Code execution, quizzes, progress tracking, and the AI tutor are available in the interactive view with JavaScript enabled.

Introduction

Before discussing the difference between `mutable` and `immutable` objects, it's important that we properly define what an `Object` is in Object-Oriented Programming (OOP). This will serve as one of the foundations/basic concepts to fully understand the topic.

So to start, an Object is a piece of data that contains its own:

  1. identity (unique name),
  2. states (characteristics or attributes) and,
  3. behaviors (methods).

For example, assume that we are going to adopt a dog (or a cat!). After adoption, we would give that dog a name to call it (to uniquely identify it-- especially when we take it outside for a walk). Our dog has different attributes, including but not limited to, breed, color, and age. Finally, the dog may perform several functions like eating, sleeping, and barking.

Let’s have a look at another example of an object:

The above figure illustrates a house having a unique house number plate. It also has certain features like roofColor and doorColor, along with certain functions like the doorOpens and doorShuts.

To extend our understanding, it's also crucial that we understand that an object is a specific "realization" of a class. You can describe a class as a logical entity which is responsible for creating individual objects. You may create multiple objects from a single class-- but it's imperative that a class always comes first whenever an object has to be created. It is a blueprint of sorts. Therefore, an object can also be defined as an instance of a class.

Keeping the above discussion in mind, let’s dive into the details of mutable and immutable objects.

0

Mutable Object And Immutable Object

Mutable Object and Immutable Object:

An object whose states and behaviors can be changed after its creation is called a mutable object.

On the other hand, an immutable object’s states and behaviors can never be changed once it is created. The idea behind creating an immutable object is to maintain its states and behaviors throughout the course of execution of the program. It's like a shield is there which keeps you from accessing these objects.

Consider the following piece of Java code to understand the basic differences between mutable and immutable objects. Since our objective is to gain understanding, we will keep our example simple.

We start with a Person class, which contains certain pieces of information about a person. It has the age attribute, a constructor that returns the name, and the methods to set and get the age of a person.

public class Person {
   int p_age;

   public Person(String name) {
      System.out.println("Name of person is :" + name );
   }

   public void setAge( int age ) {
      p_age = age;
   }

   public int getAge( ) {
      System.out.println("Age of person is :" + p_age );
      return p_age;
   }

   public static void main(String []args) {
      /* Object creation */
      Person myPerson = new Person( "Arslan" );

      myPerson.setAge( 25 );

      myPerson.getAge( );
   }
}
function Person(name) {
    this.p_age = 0;
    console.log("Name of person is :" + name);
}

Person.prototype.setAge = function(age) {
    this.p_age = age;
};

Person.prototype.getAge = function() {
    console.log("Age of person is :" + this.p_age);
    return this.p_age;
};

/* Object creation */
var myPerson = new Person("Arslan");

myPerson.setAge(25);

myPerson.getAge();
class Person:
    def __init__(self, name):
        self.p_age = 0
        print("Name of person is :", name)

    def setAge(self, age):
        self.p_age = age

    def getAge(self):
        print("Age of person is :", self.p_age)
        return self.p_age

# Object creation
myPerson = Person("Arslan")

myPerson.setAge(25)

myPerson.getAge()
#include <iostream>

class Person {
    int p_age;

public:
    Person(std::string name) {
        std::cout << "Name of person is :" << name << std::endl;
    }

    void setAge(int age) {
        p_age = age;
    }

    int getAge() {
        std::cout << "Age of person is :" << p_age << std::endl;
        return p_age;
    }
};

int main() {
    // Object creation
    Person myPerson("Arslan");

    myPerson.setAge(25);

    myPerson.getAge();

    return 0;
}
public class Person {
    int p_age;

    public Person(string name) {
        Console.WriteLine("Name of person is :" + name);
    }

    public void SetAge(int age) {
        p_age = age;
    }

    public int GetAge() {
        Console.WriteLine("Age of person is :" + p_age);
        return p_age;
    }

    public static void Main(string[] args) {
        // Object creation
        Person myPerson = new Person("Arslan");

        myPerson.SetAge(25);

        myPerson.GetAge();
    }
}
package main

import "fmt"

type Person struct {
    p_age int
}

func (p *Person) Person(name string) {
    fmt.Println("Name of person is :", name)
}

func (p *Person) setAge(age int) {
    p.p_age = age
}

func (p *Person) getAge() int {
    fmt.Println("Age of person is :", p.p_age)
    return p.p_age
}

func main() {
    // Object creation
    var myPerson Person
    myPerson.Person("Arslan")

    myPerson.setAge(25)

    myPerson.getAge()
}

On executing it, we get the following output:

Let's say we want to make this object immutable. Sadly, we can't accomplish this by simply adding a single keyword. First, we have to create an immutable class that must include specific keywords, include certain modifiers, and must exercise restraint in the code. A simple way of enforcing this constraint would be to not provide setters for your methods to avoid any change. Let's see how to make an immutable class.

How do we create an immutable class?

In order to make a class immutable,

  • our class must be declared as final. This will restrict other classes from inheriting our class and it is one of the most secure (and simplest) ways of making sure that our class can never be extended.

  • every attribute (data member) should be declared as private and final. Making an attribute final will ensure that it can never be reassigned from within the class. On the other hand, the keyword private will ensure that the attributes will not be accessed directly from outside the class. However, it is imperative to address this part in a bit of detail.

    We can even make our class immutable by declaring the attributes as public and final. Then why declare them as private? There are various reasons. The most important one is to ensure encapsulation. Doing so will reduce the unwanted risk of cross-coupling and it will restrict us from writing code that may depend on the immutable class.

  • provide getters but never provide setters so that the object’s states cannot be changed.

The main idea behind following all of the above-mentioned practices is to restrict your users from changing the states and behaviors of the object. As a result, the instances of immutable classes are unchangeable once they are created. Therefore, immutable objects, after instantiation, become read-only forever.

0

Fill In

Immutable classes have __________ methods but not __________ methods.

( Please provide your answer as comma separated strings )

Multiple Choice

A beginner Java programmer created an immutable object, but it is not functioning correctly. What is wrong with their code? (Choose from options below)

public class Car {
private final String model;
private String registrationNum;

Car (final String model) {
    this.model = model;
}

public final String printModel() {
    System.out.println(this.model);
}

How Can We Change Immutable Objects?

How can we change Immutable Objects?

If you're required to update an immutable object, there really isn't a workaround. You first have to clone that object, and then modify that cloned object in order for it to reflect your changes. Otherwise, there is no way that you can directly manipulate the immutable object.

0

Advantages Of Immutability Objects

Advantages of Immutability Objects:

  • Immutables are very useful in concurrent programming to ensure thread-safety (where an object is shared by multiple threads at a single time). You can freely share your immutable objects with various threads, without having to worry about any sort of inconsistency.

  • Immutables are very important in cases where we deal with key-value pairs which never change. For example, consider maps. We locate everything on maps using coordinates (longitude and latitudes) which always remain the same, making immutable objects as the best option here.

  • They are really useful in ATM machine-like systems where if a system failure occurs before the completion of the transaction, the user may face critical loss. With an immutable class, your account balance will only change once you have received the cash from the ATM. Otherwise, you may throw an error message and prevent losing that amount.

0

Multiple Choice

Which of the following is a default immutable class provided by Java?

Which Is Better?

Which is better?

Both of these concepts have their own benefits. Redux is used in React for state management of the application, and it heavily incorporates this concept of immutability to facilitate the data handling. Mutable objects allow you to make changes without having to create another copy, thus saving the memory that would have been allocated to the newly created object.

0

Fill In

The following code block shows a/an ___ object.

public final class myClass {
private final String name;

myClass (final String name) {
    this.name = name;
}

public final String getName() {
    return name;
}

public static void main(String[] args) {
    myClass myName = new myClass("Jake");
    System.out.println(obj.getName());
}

One Pager Cheat Sheet

One Pager Cheat Sheet

  • We must start by understanding Objects, which are pieces of data that have unique identities, states, and behaviors, to properly discuss the difference between mutable and immutable objects.
  • An immutable object's states and behaviors cannot be changed once it is created, while a mutable object's states and behaviors can be changed after its creation.
  • Instances of immutable classes are unchangeable once they are created due to their restricted access and lack of set methods.
  • The constructor has an unassigned final variable and the printModel() method should be public and return the model String.
  • We have to clone the immutable object, and modify it, as there is no way to directly manipulate it.
  • Immutable objects are useful for concurrent programming, mapping, and critical systems, providing consistency and safety.
  • Java provides default immutable classes, such as String, Boolean, and Integer, which are useful for ensuring that their values remain unaltered in complex programming scenarios.
  • Both Redux and mutable objects offer benefits and are used for different purposes, with Redux leveraging the concept of immutability to manage state and mutable objects allowing changes to be made without having to create a new copy.
  • The class myClass is immutable - its values are set during its initialization and cannot be modified afterwards.
Open interactive view →