An immutable class in Java is a class whose state of an object cannot be changed or modified after it is created.
In other simple words, a class whose objects are immutable (i.e., unmodifiable) is called immutable class in Java.
An immutable object in Java is an object whose state cannot be changed after its construction. Once we construct an object of immutable class, we cannot change or update its content.
All the wrapper classes in java like Integer, Long, Short, Byte, Boolean, Float, and Double are immutable class.
In java.time package, several classes like LocalDate, LocalDateTime, LocalTime, MonthDay, Year, YearMonth, ZonedDateTime, OffsetDateTime, and OffsetTime are immutable classes in Java.
String, Color, BigInteger, BigDecimal, CopyOnWriteArrayList and CopyOnWriteArraySet are also all immutable classes.
Immutable classes are useful in Java because we know that they will always be the same. They can be passed in different areas of a program without worrying about its changes. They help to make programs simple and maintain to easy.
How to create/make an Immutable Class in Java?
There are the following steps or guidelines for making a class immutable in Java. They are as follows:
1. All the fields should be declared final and private so that these fields cannot be accessed from outside the class.
2. Create only getter method to access the fields inside the class. Do not provide setter method inside the class so that no one can set any value to the field.
3. Restrict inheritance. Declare the class itself as final so that the derived classes do not make it mutable. This is the easiest way to prevent the inheritance. Another way is to make the constructor private and construct the instance in factory method.
4. You should initialize all the values at the time of object construction.
5. Do not allow any method to modify any object.
6. If a mutable object (like arrays, collections, StringBuffer, etc.) is passed to the parameterized constructor, the immutable class should make a defensive copy of mutable object before storing its reference.
7. Do not allow this reference to escape during object creation, such as in anonymous inner classes (e.g., adding action listener).
Example Program to create Immutable Class in Java
Let’s create a very simple program of immutable class where we will declare a class named Student as final, data members as private and final, parameterized constructor, and getter method. Look at the following source code.
Program code 1:
package javaProgram; // An immutable class. public final class Student { // Declare data members as final and private. private final String name; private final int rollNo; public Student(String name, int id) { this.name = name; this.rollNo = id; } // Declare getter methods for each private variable. public String getName() { return name; } public int getRollNo() { return rollNo; } } package javaProgram; public class ImmutableDemo { public static void main(String[] args) { Student st = new Student("John", 12); String name = st.getName(); int rollNo = st.getRollNo(); System.out.println("Name: " +name); System.out.println("Roll no: " +rollNo); } }
Output: Name: John Roll no: 12
In the preceding program, the class named Student is an immutable class because of the following reasons:
- The class has declared as final. So, no one can create a subclass of this class.
- The instance variables inside the class have declared as private and final. So, we cannot access them from outside the class and change the value of them after object creation.
- There are no setter methods declared inside the class. We have no choice to change the value of the instance variable.
All these key points makes this class as immutable in Java.
Now, in the above program, we are going to do a change something. We will add one reference type variable in this program and see what happens?
Program code 2:
package javaProgram; public final class Student { // Declare data members as final and private. private final String name; private final int rollNo; private final School sc; // School class. public Student(String name, int id, School sc) { this.name = name; this.rollNo = id; this.sc = sc; // initialization of sc. } // Declare getter methods for each private variable. public String getName() { return name; } public int getRollNo() { return rollNo; } public School getSc() { return sc; } }
In the above code, we have only added School class object as private and final. Now, we will create School class with just one data member. Look at the following source code.
package javaProgram; public class School { private String scName; public String getSchoolName() { return scName; } public void setSchoolName(String scName) { this.scName = scName; } }
Here, the question is: Is Student class still immutable class? Answer is No. It is no more immutable class because we can change the state of School object. Let’s see how?
package javaProgram; public class ImmutableDemo { public static void main(String[] args) { // Creating an object of School. School sc = new School(); sc.setSchoolName("RSVM"); // Creating an object of immutable class. Student st = new Student("John", 12, sc); String name = st.getName(); int rollNo = st.getRollNo(); System.out.println("Name: " +name); System.out.println("Roll no: " +rollNo); System.out.println("School name before modification: " +st.getSc().getSchoolName()); // Now, we will attempt to change school name. sc.setSchoolName("DPS"); System.out.println("School name after modification: " +st.getSc().getSchoolName()); } }
Output: Name: John Roll no: 12 School name before modification: RSVM School name after modification: DPS
As you can observe in this example program, we have able to change the state of object and the class Student is no more immutable class. Let’s fix this issue to make this class as immutable.
Program code 3:
package javaProgram; public final class Student { // Declare data members as final and private. private final String name; private final int rollNo; private final School sc; // School class. public Student(String name, int id, School sc) { this.name = name; this.rollNo = id; this.sc = new School(); this.sc.setSchoolName(sc.getSchoolName()); } // Declare getter methods for each private variable. public String getName() { return name; } public int getRollNo() { return rollNo; } public School getSc() { return sc; } }
In this code, we have modified Student immutable class, now school object initialization will not update the same object.
Now keep the School class and ImmutableDemo class same, with this modified immutable class. When we will run this program, the following output will generate.
Output: Name: John Roll no: 12 School name before modification: RSVM School name after modification: RSVM
As you can observe the output, that now we are no more able to change object. Now, this class is an immutable class.
Benefits of using Immutable class
There are several advantages of using immutable class in Java over mutable class.
1. Creating an immutable class is easy and understandable.
2. Testing an immutable class is simple.
3. Since we cannot modify the object after creation, an immutable class can be used in the multithreading environment safely.
4. Immutable class can also be used for caching purpose, as the state of an immutable object cannot be changed.
Mutable Class and Mutable Object in Java
A mutable class in Java is a class whose objects are mutable (i.e., modifiable). If the state of an object can be changed or mutated after it has been created, it is called mutable object in java.
Java.util.Date, StringBuffer and StringBuilder are the examples of mutable classes in Java.
When we make any change or modify in an existing mutable object, no new object will be constructed and will update the value of the existing object. A mutable object may or may not be thread-safe.
Let’s create a program of mutable class whose object’s state can be changed after object creation.
Program code 4:
package javaProgram; public class Student { // Declare data members as private. private String name; private int rollNo; public Student(String name, int id) { this.name = name; this.rollNo = id; } // Declare getter and setter methods for each private variable. public String getName() { return name; } public int getRollNo() { return rollNo; } public void setName(String name) { this.name = name; } public void setRollNo(int rollNo) { this.rollNo = rollNo; } } package javaProgram; public class MutableDemo { public static void main(String[] args) { // Creating an object of mutable class. Student st = new Student("John", 12); String name = st.getName(); int rollNo = st.getRollNo(); System.out.println("Name: " +name); System.out.println("Roll no: " +rollNo); // At this time, the instance variables store the values John and 12 which defines their states. // Now we will change the values of instance variables using getter and setter methods. st.setName("Deepak"); st.setRollNo(25); String changeName = st.getName(); int changeRollNo = st.getRollNo(); System.out.println("Name after modification: " +changeName); System.out.println("Roll no after modification: " +changeRollNo); } }
When you will run this program, the following output will produce.
Output: Name: John Roll no: 12 Name after modification: Deepak Roll no after modification: 25
As you can observe in this program, the values of instance variables has changed from John and 12 to Deepak and 25.
In other words, the states of an object has changed with the help of setName() and setRollNo() methods. This is an example of mutable class.
Advantage of Immutable object over Mutable object
There are several advantages of immutable object over mutable object. They are as follows:
1. An immutable object can be passed to different areas of a program in the same Java application without worrying about its value change.
2. It is inherently thread-safe that helps to write multithreading program code without much worries because its state cannot be changed.
3. Immutable objects are good for hash keys, as their hash code can be cached and reused for better performance.
In this tutorial, you learned how to make immutable class in java with example programs. Hope that you will have understood the basic concepts of immutable and mutable in Java with examples.
If you get anything incorrect in this tutorial, then please inform our team through email. You email will be precious to us.
Thanks for reading!!!
Next ⇒ Java String toLowerCase() Method⇐ Prev Next ⇒