Encapsulation
Encapsulation keeps an object’s data safe by hiding it and allowing changes only through methods that enforce the rules.
On this page · 5 min · Beginner
On this page
- In simple words
- Learning objectives
- Explanation
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Beginner
- Updated
- Oct 30, 2026
Related tutorials
In simple words#
An ATM never lets you touch the cash vault. You use buttons (methods) that check your PIN and balance first — that protection is encapsulation.
- private
- Visible only inside the class.
- Getter / setter
- Methods to read / change a field.
- Invariant
- A rule that is always true, e.g. balance ≥ 0.
Learning objectives#
- Make fields private
- Expose behaviour instead of raw fields
- Validate changes
- Create read-only data
Explanation#
Make fields private and provide methods for allowed actions.
Prefer meaningful methods (deposit, withdraw) over generic setters (setBalance).
Getters can expose values; omit setters for read-only data.
Return copies or unmodifiable views of internal lists so callers cannot change them.
Code example: An account that can’t go negative#
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Account {
private double balance;
private final List<String> history = new ArrayList<>();
public double getBalance() { return balance; }
public List<String> getHistory() { return Collections.unmodifiableList(history); }
public void deposit(double amount) {
if (amount <= 0) throw new IllegalArgumentException("Deposit must be positive");
balance += amount;
history.add("+" + amount);
}
public void withdraw(double amount) {
if (amount > balance) throw new IllegalStateException("Insufficient balance");
balance -= amount;
history.add("-" + amount);
}
public static void main(String[] args) {
Account acc = new Account();
acc.deposit(1000);
acc.withdraw(300);
System.out.println(acc.getBalance() + " " + acc.getHistory());
}
}
700.0 [+1000.0, -300.0]
This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.
Step-by-step explanation#
- balance is private — no direct changes.
- deposit and withdraw enforce the rules.
- History is returned read-only.
- The invariant balance ≥ 0 always holds.
Real-world use case#
Banking software guarantees no account goes negative because only withdraw() can reduce the balance.
Common mistakes#
It breaks encapsulation. Add only the operations that make sense.
Callers can modify them. Return unmodifiable views or copies.
Best practices#
- Private fields
- Behaviour methods over setters
- Validate every change
- Immutable where possible
Remember this#
Private data, public behaviour.
Methods guard the rules.
Don’t leak internal collections.
Practice exercise#
Your task: Make an Employee class whose salary can only increase via giveRaise(percent).
Show solution
public class Employee {
private double salary;
public Employee(double salary) { this.salary = salary; }
public double getSalary() { return salary; }
public void giveRaise(double percent) {
if (percent <= 0) throw new IllegalArgumentException();
salary += salary * percent / 100;
}
}
Mini quiz#
Why make fields private?
Want more? Practise all Java MCQs · Java interview questions
My notes#
Saved in this browser.