Summary: In this tutorial, you will learn about the Java immutable class and how to create an immutable class in Java.
Introduction to the Java immutable class
In Java, an immutable class is a class whose objects cannot be modifiable once they are created. An immutable class is useful when you want to ensure that the object’s state remains constant throughout its lifetime. Immutable classes have several advantages such as thread safety and ease of caching.
To create an immutable class in Java, you follow these rules:
- All fields are declared as final: This ensures that they are not modifiable after initialization.
- No setter methods: All fields must not have setter methods to prevent modification once they are initialized.
- Make deep copies for mutable fields: If the class has some fields as mutable objects, you make a deep copy of these objects when initializing them. This ensures that changes to these fields outside the class do not affect the class’s internal state.
- An immutable class cannot be subclassed by either marking it as final or making constructors
private
and providing a static method for creating objects.
Java immutable class examples
Let’s take some examples of how to create an immutable class in Java.
Example 1. Creating a simple Immutable class
The following illustrates how to define an immutable class Contact
:
public final class Contact {
private final String email;
private final String phone;
public Contact(String email, String phone) {
this.email = email;
this.phone = phone;
}
public String getEmail() {
return email;
}
public String getPhone() {
return phone;
}
@Override
public String toString() {
return "Contact{" +
"email='" + email + '\'' +
", phone='" + phone + '\'' +
'}';
}
}
Code language: Java (java)
The Contact
class is immutable because:
- Both
email
andphone
fields are declared asfinal
, making them unchangeable after initialization in the constructor. - The class has no setter methods so the
phone
andemail
cannot be changed from the outside of the class. - Since the type of
email
andphone
areString
, they are immutable. - The
Contact
class is marked asfinal
to ensure that it cannot be inherited.
Example 2: Defining a complex immutable class
Let’s take a look at an example of defining an immutable class that has a mutable field.
First, define a mutable class Author
that has two fields name
and bio
:
public class Author {
private String name;
private String bio;
public Author(String name, String bio) {
this.name = name;
this.bio = bio;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBio() {
return bio;
}
public void setBio(String bio) {
this.bio = bio;
}
@Override
public String toString() {
return "Author{" +
"name='" + name + '\'' +
", bio='" + bio + '\'' +
'}';
}
}
Code language: Java (java)
Second, define an immutable class Book
that includes a field author
with the type of Author
:
public final class Book {
private final String title;
private final String isbn;
private final Author author;
public Book(String title, String isbn, Author author) {
this.title = title;
this.isbn = isbn;
// deep copy
this.author = new Author(author.getName(), author.getBio());
}
public String getTitle() {
return title;
}
public String getIsbn() {
return isbn;
}
public Author getAuthor() {
return author;
}
@Override
public String toString() {
return "Book{" +
"title='" + title + '\'' +
", isbn='" + isbn + '\'' +
", author=" + author +
'}';
}
}
Code language: Java (java)
The Book
class is immutable because:
- The
title
andisbn
fields arefinal
, making them unchangeable after initialization in the constructor. - The
author
field is mutable but we make a deep copy of it in the constructor. It means that if theauthor
object is modified outside theBook
class, the copy of theauthor
object inside theBook
class is not changed. - The
Book
class has no setter methods that can mutate its fields such astitle
,isbn
, andauthor
. - The
Book
class is marked asfinal
to ensure that it cannot be extended.
The following example illustrates the immutability of the Book
class. Even when we change the name of the author outside of the class, the book
object itself remains unchanged:
public class App {
public static void main(String[] args) {
var author = new Author(
"Serena Everwood",
"Serena Everwood is a prolific writer."
);
var book = new Book(
"Eternal Shadows",
"978-1-234567-89-0",
author
);
// display the book
System.out.println(book);
// change the author name
author.setName("Serena Doe");
System.out.println(author);
// the book remains the same
System.out.println(book);
}
}
Code language: Java (java)
Output:
Book{title='Eternal Shadows', isbn='978-1-234567-89-0', author=Author{name='Serena Everwood', bio='Serena Everwood is a prolific writer.'}}
Author{name='Serena Doe', bio='Serena Everwood is a prolific writer.'}
Book{title='Eternal Shadows', isbn='978-1-234567-89-0', author=Author{name='Serena Everwood', bio='Serena Everwood is a prolific writer.'}}
Code language: Java (java)
Summary
- Java immutable class is a class whose objects cannot be changed once they are initialized.