Phase 9 of 20 · Topic 9.3

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.