Last Updated on October 16, 2023 by Ankit Kochar
An immutable class In Java refers to a class where the object’s state remains unalterable after its creation. Java offers various immutable classes, including well-known examples like String, Integer, and Long. It’s important to note that all Wrapper Classes in Java inherently exhibit immutability.
Let us first understand the concept of Immutability in Java, before learning about immutable classes in java in detail.
Immutability in Java
In Java, immutability signifies that an object or data structure remains unalterable once it’s instantiated. Simply put, the state of an immutable object remains fixed from its creation onwards. This characteristic proves invaluable in scenarios where multiple threads may access the object, necessitating the preservation of its state’s integrity.
To create an immutable object in Java, you should follow these steps:
Step 1: Declare all fields of the class as final and private
Step 2: Initialize the fields in the constructor
Step 3: Do not provide setter methods for changing the state of the object
Step 4: If mutable objects are used, ensure that they are also made immutable or are defensively copied in the constructor
By following these steps, you can ensure that the state of an immutable object cannot be changed once it is created, making it safer to use in multi-threaded environments.
Immutable Class in Java
An immutable class in Java is a class whose state cannot be modified after it is created. The state of an object of an immutable class in java is set during its creation and cannot be changed afterward. To achieve immutability, all fields of an immutable class must be declared as "final" and must be initialized in the constructor. Additionally, the class should not provide any setter methods that could modify the state of an object. Immutable classes are useful in situations where the state of an object must remain constant, such as in multi-threaded environments where the object may be accessed by multiple threads.
Benefits of Immutable Class in Java
There are several benefits of using immutable classes in Java:
- Immutable classes are inherently thread-safe, as their state cannot be changed once created. This makes it easy to share instances of immutable classes between multiple threads without the need for synchronization.
- Since the state cannot be changed, instances of immutable class in java can be safely shared between multiple objects without the risk of unintended modifications.
- Immutable class in Java is easier to reason about than mutable classes, as their state cannot change over time. This makes it easier to understand and predict the behavior of an application that uses immutable classes.
- Immutable class in Java can be optimized for performance by using caching and other techniques. For example, the hash code of an immutable object can be precomputed and cached, reducing the cost of hash-based operations.
- Debugging an application that uses immutable classes can be simpler, as the state of an object does not change over time. This makes it easier to isolate and diagnose issues, as there is no need to track changes to the state of objects over time.
- Immutable classes can be used effectively in caches, as their state cannot change and therefore their hash code cannot change. This allows them to be safely used as keys in hash-based collections, such as hash maps.
- Immutable objects are often reusable, as their state cannot change. This can lead to reduced memory usage and improved performance, as the same instance of an immutable object can be used in multiple places instead of creating a new instance each time.
Overall, the use of immutable classes can lead to improved performance, increased reliability, and simpler, safer code. So, now we are ready to learn how we can create an immutable class in Java.
Steps to Create Immutable Class in Java
Here are the steps to create an immutable class in Java:
Step 1: Declare the class as final:
This prevents the class from being subclassed, ensuring that the state of an object cannot be changed through inheritance.
Step 2: Make all fields private and final:
This ensures that the state of an object cannot be changed after it is created.
Step 3: Do not provide setter methods:
Do not provide any methods for changing the state of an object. This ensures that the state of an object remains constant after it is created.
Step 4: Initialize all fields in the constructor:
All fields must be initialized in the constructor and should not be modified afterward.
Step 5: Defend against mutable arguments:
If the constructor takes arguments that are mutable, ensure that they are defensively copied in the constructor so that changes to the arguments do not affect the state of the immutable object.
Step 6: Ensure that the class cannot be subclassed:
This can be done by declaring the class as final or by making the constructor private and providing static factory methods that return instances of the class.
By following these steps, you can create an immutable class in Java that is safe to use in multi-threaded environments and provides improved performance, reliability, and security.
Example of Immutable Class in Java
The code given below illustrates the correct implementation of Immutable Class in Java
final class ImmutableClass { private final int id; private final String name; public ImmutableClass(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public String getName() { return name; } } class Main{ public static void main(String args[]){ ImmutableClass obj = new ImmutableClass(123, "PrepBuddy"); System.out.println("The name of the object is "+ obj.getName()); } }
Output:
The name of the object is PrepBuddy
Explanation:
In this example, the class ImmutableClass is declared as final, which means that it cannot be subclassed. The instance variables id and name are declared as final, which means that their values cannot be changed once they are set. The only way to set the values of id and name is through the constructor. The getId and getName methods provide read-only access to the values of id and name, respectively. Because the state of an ImmutableClass object cannot be changed after it is created, ImmutableClass objects are considered to be immutable.
In the main method, we have created an object “obj” of the class “ImmutableClass”. Then we accessed the private member using the getter function defined in the class.
Immutable Classes in JDK
The Java Development Kit (JDK) includes several classes that are considered to be immutable:
- java.lang.String
- java.math.BigInteger
- java.math.BigDecimal
- java.util.UUID
- java.util.Locale
- java.util.Currency
- java.time.Instant
- java.time.LocalDate
- java.time.LocalTime
- java.time.LocalDateTime
- java.time.ZonedDateTime
- java.time.Duration
- java.time.Period
- java.nio.file.Path
- java.net.InetAddress
These classes are designed to be used as building blocks for other objects, and their immutability makes them suitable for use as keys in hash maps, as elements of sets, or as elements of collections that require immutability.
Conclusion
Immutable class in Java play a crucial role in maintaining the integrity of data and ensuring thread safety. They offer a secure way to create objects whose state cannot be modified once they are instantiated. By doing so, they eliminate potential issues related to data corruption in multithreaded environments and simplify the code by reducing the need for synchronization mechanisms.
FAQs related to Immutable Classes in Java:
Here are some FAQs related to immutable classes in Java.
1. Why are immutable classes important in Java?
Immutable classes are important for various reasons:
- They ensure thread safety by eliminating the risk of concurrent modification.
- They simplify code and reduce the need for synchronization.
- They enhance security by preventing unauthorized changes to object state.
2. What are some examples of immutable classes in Java?
Common examples include String, Integer, Long, and other wrapper classes. Additionally, user-defined immutable classes can be created by declaring all fields as final and not providing setters.
3. How do you create an immutable class in Java?
To create an immutable class, follow these guidelines:
- Declare all fields as private and final.
- Provide no setters for these fields.
- Ensure that the class itself is declared as final or that its methods are final.
- If the class contains mutable objects, return deep copies of them instead of references.
4. What are the advantages of using immutable classes?
Advantages include:
- Thread safety: Immutable objects can be safely shared among multiple threads.
- Simplified code: You don’t need to implement complex synchronization logic.
- Predictable behavior: Once created, immutable objects cannot change unexpectedly.
5. Are there any drawbacks to using immutable classes?
Immutable classes have limited use cases. They can be less efficient if frequent changes to object state are required, as they require creating new objects instead of modifying existing ones.