Middle
Why are immutable classes needed and what are their main characteristics?
sobes.tech AI
Answer from AI
Immutable classes are classes whose objects cannot be changed after creation. All their fields are declared as final and initialized once in the constructor(s).
Main characteristics:
- Thread-safety: Objects are inherently thread-safe because their state never changes. No synchronization is required to work with them.
- Simplicity: They are easier to design, implement, and use because there is no need to worry about state changes. This reduces the number of errors.
- Caching: Such objects can be safely used as keys in a
Mapor elements in aSet, since their hash code and equality (defined by theequalsmethod) do not change. - Safety: Using immutable objects prevents unwanted side effects when one part of the code modifies an object used in another part.
- Sharing: Multiple references can point to the same immutable object without the risk of changing its state.
Example:
public final class ImmutablePoint { // 1. Final class
private final int x; // 2. Final fields
private final int y;
public ImmutablePoint(int x, int y) { // 3. Initialization in constructor
this.x = x;
this.y = y;
}
public int getX() { // 4. No setters
return x;
}
public int getY() {
return y;
}
// Optional: override equals() and hashCode()
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ImmutablePoint that = (ImmutablePoint) o;
return x == that.x && y == that.y;
}
@Override
public int hashCode() {
return 31 * x + y;
}
// Optional: create new objects for "modified" states
public ImmutablePoint translate(int dx, int dy) {
return new ImmutablePoint(x + dx, y + dy);
}
}
If the class contains mutable objects as fields, to ensure immutability, it is necessary to make copies of them when passing to the constructor and when returning through getters (deep copy).