Encapsulation, Data Hiding & Defensive Copying
1Concept
Encapsulation restricts direct access to an object's components by marking fields `private` and exposing public getter/setter methods with validation logic. For mutable fields (like `Date` or `List`), Defensive Copying must be applied in getters and constructors to prevent external state corruption.
2Architecture Diagram
External Caller ---> (Attempt Direct Mutation) ---> BLOCKED (private field!) External Caller ---> [ setAge(val) ] ---> Validates (val > 0) ---> Updates field securely
3Code Example
Core Java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class EncapsulationDemo {
static class UserProfile {
private final String username;
private final List<String> roles; // Mutable collection
public UserProfile(String username, List<String> roles) {
this.username = username;
// Defensive Copying in constructor
this.roles = new ArrayList<>(roles);
}
public String getUsername() { return username; }
// Return unmodifiable view to prevent external mutation
public List<String> getRoles() {
return Collections.unmodifiableList(roles);
}
}
public static void main(String[] args) {
List<String> mutableRoles = new ArrayList<>(List.of("DEVELOPER"));
UserProfile profile = new UserProfile("Alice", mutableRoles);
mutableRoles.add("ADMIN"); // External mutation attempt
System.out.println("User Roles in profile: " + profile.getRoles() + " (Protected from external mutation!)");
}
}4Expected Output
User Roles in profile: [DEVELOPER] (Protected from external mutation!)
5Key Takeaways
- ✓Always make fields private unless there is an architectural reason not to.
- ✓Returning mutable collections directly from getters breaks encapsulation.
- ✓Use `Collections.unmodifiableList()` or `List.copyOf()` for defensive copies.