How to Create Immutable Class in Java?
An immutable class in Java is a class whose objects cannot be modified after creation.
In simple words:
Once an immutable object is created, its data remains permanently unchanged.
Why Immutable Classes are Important?
Immutable classes provide:
- Thread safety
- Better security
- Reliable object behavior
- Safe caching
- Concurrency support
Immutable Class Creation Flow
Declare final Class
|
v
Make Fields private final
|
v
Initialize Using Constructor
|
v
Avoid Setter Methods
|
v
Return Defensive Copies
Main Rules to Create Immutable Class
- Declare class as final
- Make all fields private
- Make all fields final
- Initialize fields through constructor
- Do not provide setter methods
- Use defensive copying for mutable objects
Rule 1: Declare Class as final
The class should be final to prevent inheritance.
Example
final class Employee {
}
Why Important?
Child classes may break immutability by adding setter methods.
Problem Without final
class Employee {
}
class Manager extends Employee {
void setName(String name) {
}
}
Rule 2: Make Fields private
Fields should not be directly accessible outside class.
Example
private int id;
Why Important?
Direct access allows modification.
Invalid Example
public int id;
Problem
employee.id = 200;
Object state changes externally.
Rule 3: Make Fields final
final fields can only be assigned once.
Example
private final int id;
Why Important?
Prevents reassignment after initialization.
Rule 4: Initialize Fields Through Constructor
Constructor initializes immutable state.
Example
Employee(int id, String name) {
this.id = id;
this.name = name;
}
Object Initialization Flow
Object Created
|
v
Constructor Executes
|
v
Fields Assigned Once
|
v
Object Becomes Immutable
Rule 5: Do Not Provide Setter Methods
Setter methods allow modification after creation.
Invalid Example
public void setName(String name) {
this.name = name;
}
Why Dangerous?
Object state changes after creation.
Complete Immutable Class Example
final class Employee {
private final int id;
private final String name;
Employee(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
Why This Class is Immutable?
- Class is final
- Fields are private
- Fields are final
- No setter methods
- Fields initialized only once
Immutable Class Internal Working
Object Created in Heap
|
v
Values Assigned Once
|
v
Read-Only Access Allowed
Problem with Mutable Objects
Special care is needed when immutable class contains mutable objects.
Example
private final Date joiningDate;
Why Problem?
Date object is mutable. External code can modify it.
Solution: Defensive Copy
Create copies instead of storing original mutable object.
Immutable Class with Defensive Copy
final class Employee {
private final Date joiningDate;
Employee(Date joiningDate) {
this.joiningDate =
new Date(
joiningDate.getTime()
);
}
public Date getJoiningDate() {
return new Date(
joiningDate.getTime()
);
}
}
Defensive Copy Flow
Original Mutable Object
|
v
Copy Created
|
v
Internal Object Protected
Why Defensive Copy is Important?
Without defensive copy:
- External code can modify internal state.
Invalid Example
this.joiningDate = joiningDate;
Problem
joiningDate.setTime(0);
Internal immutable object gets modified.
Immutable vs Mutable Class
| Feature | Immutable Class | Mutable Class |
|---|---|---|
| Object State | Cannot Change | Can Change |
| Thread Safety | Yes | No |
| Security | High | Lower |
| Synchronization Required | No | Often Yes |
Why Immutable Objects are Thread-Safe?
Because object state never changes after creation.
Thread Safety Diagram
Multiple Threads
|
v
Shared Immutable Object
|
v
No Data Modification Possible
String Class is Immutable
Java String class is one of the best examples of immutable class.
Example
String name = "Java";
name.concat(" Programming");
System.out.println(name);
Output
Java
Why?
concat() creates new object instead of modifying existing object.
Immutable Class in Banking Systems
Banking applications use immutable classes for:
- Transaction IDs
- Audit records
- Security tokens
- Account snapshots
Example
final class TransactionId {
private final String id;
}
Immutable Class in E-Commerce Systems
E-commerce platforms use immutable classes for:
- Order IDs
- Invoice details
- Payment references
- Audit events
Immutable Classes in Spring Boot
Spring Boot applications use immutable classes for:
- DTOs
- Configuration objects
- JWT tokens
- API response models
Spring Boot Example
public final class UserResponse {
private final String name;
private final String email;
public UserResponse(
String name,
String email
) {
this.name = name;
this.email = email;
}
}
Immutable Classes in Microservices
Microservices architectures use immutable classes for:
- Kafka events
- Distributed messages
- Cloud configurations
- REST API contracts
Java Records for Immutable Classes
Modern Java provides:
record
to simplify immutable object creation.
Example
record Employee(
int id,
String name
) {
}
Why Records are Useful?
- Less boilerplate code
- Immutable by default
- Cleaner syntax
- Better readability
Immutable Object Memory Flow
Object Created
|
v
State Stored Permanently
|
v
Read-Only Access Shared Safely
Advantages of Immutable Classes
- Thread safety
- Better security
- Easier debugging
- Reliable caching
- No synchronization overhead
Disadvantages of Immutable Classes
- More object creation
- Higher memory usage sometimes
- Defensive copying complexity
Common Interview Mistake
Many developers think final keyword alone makes class immutable.
Actually:
- Fields must also be private and final.
- No setters should exist.
Another Common Mistake
Many developers think immutable classes cannot contain mutable objects.
Actually:
- Mutable objects can be handled safely using defensive copies.
Best Practices
- Prefer immutable objects for shared data
- Use defensive copying carefully
- Keep object state minimal
- Use records for simple immutable models
Realtime Enterprise Example
JWT Security Token
final class JwtToken {
private final String token;
private final long expiry;
}
Security token should never change after creation.
Related Learning Topics
- What is Immutable Class in Java
- What is final Keyword in Java
- What is Object Cloning in Java
- Difference Between Shallow Copy and Deep Copy
- Garbage Collection in Java
- What is Polymorphism
- OOPS in Java
- What is Spring Boot
- What are Microservices
Professional Interview Answer
To create an immutable class in Java, the class should generally be declared final, all fields should be private and final, values should be initialized through constructors, setter methods should be avoided, and defensive copies should be used for mutable objects. Immutable classes ensure that object state cannot change after creation, making them thread-safe, secure, and reliable. Java String class is a common immutable class example. Enterprise systems, Spring Boot applications, banking platforms, and microservices architectures widely use immutable objects for DTOs, security tokens, transaction snapshots, distributed events, and configuration management.
Frequently Asked Questions
How do you create immutable class in Java?
Declare class final, make fields private final, initialize through constructor, avoid setters, and use defensive copying.
Why should immutable class be final?
To prevent inheritance from breaking immutability.
Why are immutable objects thread-safe?
Because object state never changes after creation.
What is defensive copying?
Creating copies of mutable objects to protect internal state.
Are Java records immutable?
Yes, Java records are immutable by default.