Java Immutable & Wrapper Classes
Immutable Class
Section titled βImmutable Classβ1. What makes a class immutable? List all conditions.
Section titled β1. What makes a class immutable? List all conditions.βA class is considered immutable when its state cannot change after creation.
To achieve immutability, the class must follow these rules:
- Declare the class as
final
β Prevents subclassing (otherwise a child class could modify behavior). - Make all fields private and final
β Prevents external modification & ensures values never rebind. - Do not provide setters
β State cannot be reassigned after object creation. - Initialize fields only in constructor
β The objectβs state is set once. - Perform deep copy of mutable objects
β Prevents clients from modifying internal state by reference. - Return deep copies (not original references) in getters
β Ensures internal fields remain protected.
2. Why must mutable fields be deeply copied in getters and constructors?
Section titled β2. Why must mutable fields be deeply copied in getters and constructors?βIf you store or return mutable objects (e.g., List, Date, Map) by reference, callers can modify them, which breaks immutability.
this.list = new ArrayList<>(inputList); // Defensive copy in constructorreturn new ArrayList<>(this.list); // Defensive copy in getterDeep copying preserves the internal state, ensuring the object truly remains immutable.
3. Is final keyword enough to make a class immutable? Explain.
Section titled β3. Is final keyword enough to make a class immutable? Explain.ββ No.
final only prevents reassignment of reference, not modification of the object itself.
Example:
final List<String> list = new ArrayList<>();list.add("X"); // Allowed β internal state changesSo, immutability requires both:
finalreference fields and- No modification to underlying objects (via deep copy).
4. Why is immutability useful in multi-threading and caching?
Section titled β4. Why is immutability useful in multi-threading and caching?β| Benefit | Explanation |
|---|---|
| Thread-safety | Immutable objects cannot change, so no need for synchronization. Multiple threads can safely share the same instance. |
| Safe caching | Cached objects cannot be tampered with β predictable reads. |
| Memory efficiency | One shared instance instead of making multiple copies. |
This is why String, Integer, LocalDate, and BigDecimal are immutable.
5. Give an example where immutable objects improve system safety.
Section titled β5. Give an example where immutable objects improve system safety.βExample: Using String for database connection URLs, authentication tokens, etc.
If String were mutable:
- Someone could modify password tokens in memory
HashMapkeys would become inconsistent- Logging systems could leak confidential updates
Immutability prevents these critical risks.
Wrapper Class & Autoboxing
Section titled βWrapper Class & Autoboxingβ1. What are wrapper classes in Java and why do we need them?
Section titled β1. What are wrapper classes in Java and why do we need them?βWrapper classes are object representations of primitive types, e.g.:
| Primitive | Wrapper |
|---|---|
int | Integer |
double | Double |
boolean | Boolean |
We need wrappers because:
- Collections (e.g.,
List,Map) cannot store primitives - Frameworks (Spring, Hibernate, JSON) rely on objects, not primitives
- Wrappers provide useful utility methods and constants
2. Explain autoboxing and unboxing. What performance issues can arise?
Section titled β2. Explain autoboxing and unboxing. What performance issues can arise?β- Autoboxing: Converting primitive β wrapper automatically
Example:Integer x = 10; - Unboxing: Converting wrapper β primitive automatically
Example:int y = x;
Performance concerns:
- Autoboxing creates new wrapper objects, increasing heap usage.
- Excessive boxing/unboxing in loops can cause GC overhead and performance drops.
3. How does Integer caching work and what values are cached?
Section titled β3. How does Integer caching work and what values are cached?βJava maintains a cache for Integer values from -128 to +127.
Integer a = 100;Integer b = 100;a == b // true (same cached object)Values outside this range are new objects:
Integer x = 200;Integer y = 200;x == y // false (different objects)This improves memory usage and speeds up frequently-used small integers.
4. What is the result of comparing two Integers with == vs equals()? Explain memory impact.
Section titled β4. What is the result of comparing two Integers with == vs equals()? Explain memory impact.β| Comparison | Behavior | Example | Result |
|---|---|---|---|
== | Compares object references | Integer a = 128; Integer b = 128; a == b | false (different objects) |
.equals() | Compares values | a.equals(b) | true |
Key point:
- For values between -128 to +127,
==may betruebecause cached object is reused. - For values outside this range,
==is false because new objects are created.