DevNotes
Support
Core Java · Chapter 07

Immutable Objects

What immutability means, why Java relies on it, and the rules for building truly immutable classes.

◷ 6 min read§ 21 sections? 10 interview questions{ } 21 code examples

#Introduction

One of the most frequently asked Java interview questions is: What is an Immutable Object?

Understanding immutability is crucial because many core Java classes are immutable, including:

  • String
  • Most classes in the java.time package
  • BigInteger
  • BigDecimal
  • Wrapper classes (Integer, Long, etc.)

Immutable objects are widely used in enterprise applications because they are:

  • Thread-safe
  • Secure
  • Easy to cache
  • Reliable as HashMap keys

#What is an Immutable Object?

An immutable object is an object whose state cannot be changed after it is created. Once constructed, its data remains constant throughout its lifetime.

Java
String name = "Java";
name.concat(" 21");
System.out.println(name);
Output
Java

The original object is unchanged.

#Mutable vs Immutable

Mutable Object

Java
StringBuilder sb = new StringBuilder("Java");
sb.append("21");
Output
Java21

The same object is modified.

Immutable Object

Java
String s = "Java";
s.concat("21");
Output
Java

A new object is created instead of modifying the existing one.

#Memory Representation

Java
String s = "Java";
s = s.concat("17");
Befores → "Java"
After concats → "Java17"
Old object"Java"eligible for GC
The original object never changes

#Why Does Java Use Immutable Objects?

Imagine multiple threads sharing the same object. If one thread changes it, all other threads observe the modified data. This may lead to inconsistent results.

With immutable objects, no thread can modify the shared state. Therefore, immutable objects are inherently thread-safe.

#Advantages of Immutable Objects

1. Thread Safety

No synchronization required. Multiple threads can safely share the same object.

2. Security

Sensitive information cannot be modified accidentally.

Java
String username = "admin";

No code can change the contents of this String object.

3. Safe HashMap Keys

Hash-based collections rely on stable hash codes.

Java
Map<String, String> map = new HashMap<>();

Since String never changes, its hash code never changes. Therefore, lookups remain consistent.

4. Easy Caching

Immutable objects can be cached safely because their values never change. Example: the String Pool — "Java" is shared by multiple references.

5. Easy Debugging

No unexpected state changes. Objects behave predictably.

#How to Create an Immutable Class?

There are several rules.

Rule 1 — Declare the class as final

Java
public final class Employee {
}

Why? To prevent inheritance. Otherwise, a subclass could make the object mutable.

Rule 2 — Declare all fields as private

Java
private int id;
private String name;

Encapsulation protects internal state.

Rule 3 — Declare fields as final

Java
private final int id;
private final String name;

Values can only be assigned once.

Rule 4 — Initialize fields through the constructor

Java
public Employee(int id, String name) {
    this.id = id;
    this.name = name;
}

Rule 5 — Do not provide setter methods

Wrong:

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

Never expose setters in immutable classes.

Rule 6 — Provide only getters

Java
public int getId() {
    return id;
}

Read-only access.

#Complete Immutable Class

Java
public final class Employee {

    private final int id;
    private final String name;

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return id + " " + name;
    }
}

Once created, this object can never change.

#Immutable Class with Mutable Fields

Java
class Employee {
    private final Date joiningDate;
}

Problem: Date is mutable. Even without setters, someone can modify the date.

Wrong:

Java
Date d = employee.getJoiningDate();
d.setTime(0);

Employee is no longer immutable.

#Defensive Copying

Correct approach — constructor:

Java
this.joiningDate = new Date(joiningDate.getTime());

Getter:

Java
return new Date(joiningDate.getTime());

Every access returns a copy. The original object remains protected.

#Immutable Collections

Wrong:

Java
private final List<String> skills;

// getter
return skills;

The caller can modify the list. Correct:

Java
return List.copyOf(skills);
// or
return Collections.unmodifiableList(skills);

This prevents external modification.

#Immutable Objects in Java

These classes are immutable:

CategoryClasses
TextString
WrappersInteger, Long, Double, Character
Big numbersBigInteger, BigDecimal
Date & timeLocalDate, LocalTime, LocalDateTime
IdentifiersUUID

#Records and Immutability

Java Records naturally support immutable data.

Java
public record Employee(int id, String name) {
}

Automatically provides:

  • final fields
  • Constructor
  • Getters (accessor methods)
  • equals()
  • hashCode()
  • toString()

Records are ideal for DTOs and immutable data carriers.

#Builder Pattern

For objects with many fields, creating immutable objects using constructors becomes difficult.

Java
Employee employee = new Employee.Builder()
        .id(101)
        .name("John")
        .department("IT")
        .salary(50000)
        .build();

The Builder creates the object, which remains immutable after construction.

#Real Project Examples

Configuration Objects

Database configuration, application configuration, security configuration. Configuration rarely changes — immutable objects are ideal.

DTOs

Request DTO, Response DTO, Event DTO — often implemented as immutable objects or records.

Cache Objects

Objects stored in caches should not change unexpectedly.

#Interview Questions

Q1What is an immutable object?

An object whose state cannot be changed after construction.

Q2Why is String immutable?

For security, thread safety, caching, and efficient use of the String Constant Pool.

Q3Can immutable objects have constructors?

Yes. Constructors initialize state exactly once.

Q4Can immutable classes have mutable fields?

Yes, but defensive copying is required to preserve immutability.

Q5Why should immutable classes be final?

To prevent subclasses from introducing mutable behaviour.

Q6Why avoid setters?

Setters allow modification after construction, breaking immutability.

Q7Can immutable objects be shared between threads?

Yes. They are inherently thread-safe.

Q8Which Java feature helps create immutable data classes?

Records.

Q9Can immutable objects improve performance?

Yes. They simplify caching, reduce synchronization overhead, and are safe to share across threads.

Q10When should we create immutable classes?

Whenever object state should never change after creation, especially for DTOs, configuration objects, value objects, cache keys, and identifiers.

#Common Mistakes

  • Returning mutable collections directly.
  • Returning mutable Date objects.
  • Providing setters.
  • Forgetting to declare fields as final.
  • Allowing inheritance for immutable classes.

#Best Practices

  • Make immutable classes final.
  • Declare all fields private final.
  • Initialize all fields through constructors.
  • Never expose setters.
  • Use defensive copies for mutable fields.
  • Prefer Records for simple immutable data models.

#Quick Revision

Immutable Object
final class
private final fields
Constructor Initialization
No Setters
Only Getters
Defensive Copy
Thread Safe

#Interview Cheat Sheet

RequirementBest Practice
Prevent inheritancefinal class
Prevent field updatesprivate final
Object initializationConstructor
Prevent modificationNo setters
Mutable fieldDefensive copy
Simple immutable DTORecord

#Chapter Summary

After completing this chapter, you should be able to:

  • Explain immutability and its advantages.
  • Create fully immutable Java classes.
  • Protect mutable fields using defensive copying.
  • Understand why immutable objects are thread-safe.
  • Know when to use immutable classes, records, and the Builder pattern.
  • Confidently answer interview questions related to immutable objects in Java.