Immutable vs Mutable objects in Java

1. Introduction

In Java, objects are categorized based on their ability to change after creation. Objects that cannot be changed after creation are called immutable, while objects that can be changed are known as mutable.

2. Key Points

1. Immutable objects do not allow their state to be modified after creation.

2. Mutable objects have fields that can be changed, methods that can alter the state, or both.

3. String objects in Java are immutable, whereas StringBuilder and StringBuffer are mutable.

4. Immutable objects are inherently thread-safe as they cannot be changed after creation.

3. Differences

Immutable Mutable
Once created, their state (the values of their fields) cannot be changed. Their state can be changed after they are created.
Creating a new object is required if you need an object with a different state. State changes can be made to the existing object without creating a new one.
Examples include String, Integer, Float, and other wrapper classes. Examples include StringBuilder, ArrayList, and custom classes not specifically designed to be immutable.
Safer for multithreaded applications as they cannot be modified after creation, eliminating synchronization concerns. It may require careful synchronization in multithreaded environments to avoid concurrent modification issues.
Can be freely shared between multiple threads or objects without risk of data being altered. Sharing between threads or objects may require defensive copying or synchronization to ensure integrity.
Hashcode caching is possible because their hashcode will never change, which can benefit collections like HashSet and HashMap. Hashcode caching is less practical as their state and thus hashcode can change.

4. Example

// Example of Immutable object - String
String s = "Hello";
s.concat(" World"); // This does not change the String referenced by 's'
System.out.println(s); // Will print "Hello"

// Example of Mutable object - StringBuilder
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // This changes the internal state of the StringBuilder object
System.out.println(sb); // Will print "Hello World"

Output:

Hello
Hello World

Explanation:

1. The String object 's' does not change when concat is called because Strings are immutable. Any change produces a new String object.

2. The StringBuilder object 'sb' changes its internal state with the append method, showing mutability as it allows changes to its state after creation.

5. When to use?

Use immutable objects when you need objects that do not change over time, which simplifies development and debugging and enhances performance by reducing the need for synchronization.

Mutable objects are useful when data is expected to change frequently or when performance is a concern, such as in high-volume environments where object creation (and subsequent garbage collection) would be too costly.

Comments