Table of contents
1.
Introduction
2.
What Does Mutability Mean? Why It Matters in Java?
2.1.
Why Mutability Matters in Java
3.
Mutable Objects
3.1.
Example
4.
How to Create a Mutable Class  
5.
Immutable Objects
5.1.
Example
6.
How to Create an Immutable Class  
7.
Mutable & Immutable Class Examples
7.1.
Mutable Class Example
7.2.
Immutable Class Example
8.
Mutable vs Immutable Objects: Key Differences
9.
Advantages and Uses of Mutable & Immutable Objects
9.1.
Mutable Objects
9.2.
Immutable Objects
10.
Disadvantages and Uses of Mutable & Immutable Objects
10.1.
Mutable objects 
10.2.
Immutable Objects
10.3.
Uses
11.
Frequently Asked Questions
11.1.
Why is String immutable in Java?
11.2.
When should I use StringBuilder or StringBuffer?
11.3.
Can we create a mutable version of String?
12.
Conclusion
Last Updated: Jun 13, 2025
Medium

Mutable and Immutable Objects in Java

Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

In Java, objects are classified as mutable or immutable based on whether their state can be changed after creation. Mutable objects allow modifications, whereas immutable objects remain constant once assigned. Strings and wrapper classes are examples of immutable objects, while collections and custom classes with setter methods are mutable. Understanding mutability helps in writing efficient, thread-safe code. 

Mutable and Immutable Objects in Java

In this article, you will learn the differences, benefits, and examples of mutable and immutable objects in Java.

What Does Mutability Mean? Why It Matters in Java?

In Java, mutability refers to an object’s ability to change its internal state after it has been created. For example, if you have a StringBuilder object and you append new text to it, the original object gets modified—this is mutability. In contrast, immutable objects like String cannot be changed once created; any modification results in a new object.

Why Mutability Matters in Java

  • Memory Management: Mutable objects can save memory by avoiding the creation of multiple new objects, which is useful in performance-critical applications.
     
  • Thread Safety: Immutable objects are inherently thread-safe because their state cannot change after creation, making them suitable for multi-threaded environments.
     
  • Design Clarity: Knowing whether an object is mutable or immutable helps developers avoid unexpected side effects and bugs, especially when passing objects between methods or classes.
     

Understanding mutability in Java helps you write safer, more predictable, and efficient code.

Mutable Objects

A mutable object is an object whose state can be changed after it is created. In Java the StringBuilder and StringBuffer classes are used to create mutable strings. These classes allow modification of string content without creating new objects, making them memory efficient.

Example

public class MutableStringExample {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("Hello");
        System.out.println("Before modification: " + sb);
        
        sb.append(" World");
        System.out.println("After modification: " + sb);
    }
}
You can also try this code with Online Java Compiler
Run Code

 

Output:

Before modification: Hello
After modification: Hello World

 

Explanation:

  • StringBuilder allows us to modify the string without creating a new object.
  • The append() method modifies the existing string rather than creating a new one.

How to Create a Mutable Class  

A mutable class in Java is one where the state (or data) of the object can be changed after it is created. This means you can modify the values of its fields without creating a new object. Mutable classes are useful when you need to update the object’s state frequently.  

To create a mutable class, you need to follow these steps:  

1. Define the class with private fields: These fields will store the data.  
 

2. Provide public setter methods: These methods allow you to modify the values of the fields.  
 

3. Provide public getter methods: These methods allow you to access the values of the fields.  

Let’s create a simple mutable class called `MutableString`. This class will have a single field called `value` to store a string.  

public class MutableString {
    // Step 1: Define a private field
    private String value;

    // Step 2: Provide a constructor to initialize the field
    public MutableString(String value) {
        this.value = value;
    }

    // Step 3: Provide a getter method to access the field
    public String getValue() {
        return value;
    }

    // Step 4: Provide a setter method to modify the field
    public void setValue(String value) {
        this.value = value;
    }

    // Optional: Override toString() for better readability
    @Override
    public String toString() {
        return "MutableString{" +
                "value='" + value + '\'' +
                '}';
    }
}
You can also try this code with Online Java Compiler
Run Code

 

In this Code:   

1. Private Field: The `value` field is private, meaning it cannot be accessed directly from outside the class. This is a good practice to ensure encapsulation.  
 

2. Constructor: The constructor initializes the `value` field when an object of `MutableString` is created.  
 

3. Getter Method: The `getValue()` method allows you to retrieve the current value of the `value` field.  
 

4. Setter Method: The `setValue()` method allows you to change the value of the `value` field after the object is created.  
 

For example: 

Let’s see how this class works in practice:  

public class Main {
    public static void main(String[] args) {
        // Create an object of MutableString
        MutableString mutableString = new MutableString("Hello");

        // Print the initial value
        System.out.println("Initial Value: " + mutableString.getValue());

        // Modify the value using the setter method
        mutableString.setValue("World");

        // Print the updated value
        System.out.println("Updated Value: " + mutableString.getValue());
    }
}
You can also try this code with Online Java Compiler
Run Code

 

 Output  

Initial Value: Hello  
Updated Value: World  

 

In this example, we created a `MutableString` object with the initial value `"Hello"`. Later, we changed the value to `"World"` using the `setValue()` method. This demonstrates the mutability of the class.  

Immutable Objects

An immutable object is an object whose state cannot be changed after it is created. The String class in Java is immutable, meaning any modification creates a new string object instead of changing the existing one.

Example

public class ImmutableStringExample {
    public static void main(String[] args) {
        String str = "Hello";
        System.out.println("Before modification: " + str);
        
        str = str.concat(" World");
        System.out.println("After modification: " + str);
    }
}
You can also try this code with Online Java Compiler
Run Code

 

Output:

Before modification: Hello
After modification: Hello World

 

Explanation:

  • The original string "Hello" remains unchanged.
     
  • A new string "Hello World" is created and assigned to str, while the old string is discarded.

How to Create an Immutable Class  

An immutable class in Java is one where the state (or data) of the object cannot be changed after it is created. Once an object of an immutable class is created, its fields remain constant throughout its lifetime. Immutable classes are useful when you want to ensure that the data remains unchanged, which can help in writing thread-safe & bug-free code.  

To create an immutable class, you need to follow these steps:  

1. Define the class as final: This prevents the class from being extended.  
 

2. Make all fields private & final: This ensures that the fields cannot be modified after initialization.  
 

3. Do not provide setter methods: Since the fields are final, they cannot be modified, so no setter methods are needed.  
 

4. Initialize all fields through a constructor: This ensures that the fields are set only once during object creation.  
 

5. Return a copy of mutable fields: If the class has mutable fields (like arrays or collections), return a copy of them instead of the actual reference to prevent external modification.  
 

Let’s create a simple immutable class called `ImmutableString`. This class will have a single field called `value` to store a string.  

// Step 1: Define the class as final
public final class ImmutableString {
    // Step 2: Make the field private & final
    private final String value;

    // Step 3: Initialize the field through a constructor
    public ImmutableString(String value) {
        this.value = value;
    }

    // Step 4: Provide a getter method to access the field
    public String getValue() {
        return value;
    }

    // Optional: Override toString() for better readability
    @Override
    public String toString() {
        return "ImmutableString{" +
                "value='" + value + '\'' +
                '}';
    }
}
You can also try this code with Online Java Compiler
Run Code

 

In this Code:   

1. Final Class: The class is marked as `final` to prevent inheritance. This ensures that no subclass can override its behavior & make it mutable.  
 

2. Private & Final Field: The `value` field is private & final, meaning it cannot be accessed directly or modified after initialization.  
 

3. Constructor: The constructor initializes the `value` field when an object of `ImmutableString` is created.  
 

4. Getter Method: The `getValue()` method allows you to retrieve the current value of the `value` field. Since the field is final, it cannot be modified.  

 

For example:   

Let’s see how this class works in practice:  

public class Main {
    public static void main(String[] args) {
        // Create an object of ImmutableString
        ImmutableString immutableString = new ImmutableString("Hello");

        // Print the value
        System.out.println("Value: " + immutableString.getValue());

        // Attempting to modify the value will result in a compilation error
        // immutableString.setValue("World"); // This line will cause an error
    }
}
You can also try this code with Online Java Compiler
Run Code

 

 Output  

Value: Hello  

 

In this example, we created an `ImmutableString` object with the value `"Hello"`. Since the class is immutable, there is no way to change the value of the `value` field after the object is created. Any attempt to modify the value will result in a compilation error.  

Mutable & Immutable Class Examples

Mutable Class Example

class MutableClass {
    private StringBuilder name;
    
    public MutableClass(String name) {
        this.name = new StringBuilder(name);
    }
    
    public void setName(String name) {
        this.name.replace(0, this.name.length(), name);
    }
    
    public String getName() {
        return name.toString();
    }
    
    public static void main(String[] args) {
        MutableClass obj = new MutableClass("John");
        System.out.println("Before: " + obj.getName());
        obj.setName("Alice");
        System.out.println("After: " + obj.getName());
    }
}
You can also try this code with Online Java Compiler
Run Code

 

Output:

Before: John
After: Alice

Immutable Class Example

final class ImmutableClass {
    private final String name;
    
    public ImmutableClass(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
    
    public static void main(String[] args) {
        ImmutableClass obj = new ImmutableClass("John");
        System.out.println("Name: " + obj.getName());
    }
}
You can also try this code with Online Java Compiler
Run Code

 

Output:

Name: John

 

Explanation:

  • ImmutableClass is declared as final, preventing subclassing.
     
  • The name variable is declared as final, ensuring it cannot be modified after assignment.
     
  • No setter method is provided, keeping the object immutable.

Mutable vs Immutable Objects: Key Differences

FeatureMutable String (StringBuilder, StringBuffer)Immutable String (String)
ModificationAllowed, modifies the same objectNot allowed, creates a new object
Memory EfficiencyMore efficient, no extra object creationLess efficient, new objects created
PerformanceFaster for modificationsSlower for frequent modifications
Thread SafetyStringBuffer is thread-safe, StringBuilder is notString is thread-safe

Advantages and Uses of Mutable & Immutable Objects

Mutable Objects

  • Efficient for frequent modifications: Avoids unnecessary object creation.
     
  • Used in string manipulation operations: Useful in cases like file reading and writing, database queries, and large text processing.
     
  • Better performance in loops: When modifying strings inside loops, StringBuilder improves efficiency.

Immutable Objects

  • Security: Prevents unintended modifications, making them useful in security-sensitive applications.
     
  • Thread Safety: Since they cannot be modified, immutable objects do not require synchronization in multi-threaded environments.
     
  • Caching: Frequently used immutable objects can be cached to improve performance (e.g., String literals in Java).

Disadvantages and Uses of Mutable & Immutable Objects

Mutable objects 

  • Thread Safety Issues: Since their state can change, mutable objects require extra care in multi-threaded environments, often needing synchronization.
     
  • Unexpected Side Effects: When passed around, any method can change their state, leading to bugs that are hard to trace.
     
  • Harder Debugging: Tracking the source of data changes becomes more difficult with mutable state spread across code.

Immutable Objects

  • Higher Memory Usage: Each change creates a new object, increasing memory allocation, especially in large or frequent data manipulations.
     
  • Less Flexibility: You can't modify the existing object; instead, you need to recreate it with the new values.
     
  • Performance Overhead: Repeated object creation can lead to CPU and garbage collection overhead in memory-intensive applications.

Uses

Mutable Objects:

  • Ideal for caching, GUI elements, or data models where frequent changes are required.
     
  • Useful in scenarios demanding performance with low concurrency requirements.

Immutable Objects:

  • Perfect for multi-threaded applications and constants.
     
  • Commonly used in Java collections (e.g., keys in maps) and data transfer objects (DTOs) to ensure consistency and safety.

Frequently Asked Questions

Why is String immutable in Java?

String is immutable for security, thread safety, and efficient memory management. It allows Java to optimize performance by reusing string literals.

When should I use StringBuilder or StringBuffer?

Use StringBuilder when performance is a priority and single-threaded execution is involved. Use  StringBuffer when multiple threads need access to the same object.

Can we create a mutable version of String?

Yes, we can use StringBuilder or StringBuffer to create mutable string objects in Java.

Conclusion

In this article, we learned mutable and immutable objects in JavaMutable objects allow modifications after creation, while immutable objects remain unchanged once initialized. Classes like String are immutable, whereas StringBuilder is mutable. Understanding these concepts is crucial for memory management, thread safety, and performance optimization in Java applications.

Live masterclass