Skip to content
  • Encapsulation · Java

Encapsulation

LearnViaNotes @learnvianotes· 3 min read

Keep fields private and expose behaviour through methods, so the class alone guarantees that its state is always valid.

Why it matters

Getters, setters and validation

Java
public class Main {
    public static void main(String[] args) {
        Account acc = new Account("Asha", 1000);
        acc.withdraw(300);
        System.out.println(acc.getOwner() + ": " + acc.getBalance());
        try {
            acc.withdraw(5000);
        } catch (IllegalArgumentException e) {
            System.out.println("rejected: " + e.getMessage());
        }
        System.out.println("balance still " + acc.getBalance());
    }
}

class Account {
    private final String owner;
    private long balance;                  // hidden: no one can set it to -1

    Account(String owner, long opening) {
        if (owner == null || owner.isBlank()) throw new IllegalArgumentException("owner required");
        this.owner = owner;
        this.balance = opening;
    }

    String getOwner() { return owner; }
    long getBalance() { return balance; }  // read-only: no setBalance()

    void withdraw(long amount) {
        if (amount <= 0 || amount > balance)
            throw new IllegalArgumentException("invalid amount " + amount);
        balance -= amount;
    }
}
Output
Asha: 700
rejected: invalid amount 5000
balance still 700

Leaking mutable state — and defensive copies

Java
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> input = new ArrayList<>(List.of("math", "physics"));
        Leaky leaky = new Leaky(input);
        Safe safe = new Safe(input);

        input.add("hacked");                 // caller mutates its own list
        leaky.getSubjects().clear();         // caller mutates via the getter

        System.out.println("leaky: " + leaky.getSubjects());
        System.out.println("safe:  " + safe.getSubjects());
        try {
            safe.getSubjects().add("x");
        } catch (UnsupportedOperationException e) {
            System.out.println("safe getter is read-only");
        }
    }
}

class Leaky {
    private final List<String> subjects;
    Leaky(List<String> subjects) { this.subjects = subjects; }   // stores caller's list
    List<String> getSubjects() { return subjects; }              // hands out internals
}

class Safe {
    private final List<String> subjects;
    Safe(List<String> subjects) { this.subjects = List.copyOf(subjects); }   // copy in
    List<String> getSubjects() { return subjects; }                          // already unmodifiable
}
Output
leaky: []
safe:  [math, physics]
safe getter is read-only

Encapsulation vs abstraction

EncapsulationAbstraction
FocusHow data is protectedWhat is exposed
Mechanismprivate fields, accessors, validationInterfaces, abstract classes, simple method names
LevelImplementationDesign

How do you achieve encapsulation in Java?

Is a class with private fields and public getters/setters for all of them encapsulated?

What is a JavaBean?

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report