Beginner · Classes and objects · topic 18 of 60 · 25 min
Encapsulation: private fields, getters and setters
Explanation
Why hide data?
If balance is a public field, any line of code anywhere can write account.balance = -50000;. Nothing stops it, and when the bug appears you must search the whole codebase. If balance is private, the only way to change it is through the class's own methods, which can check every change. This is encapsulation: the object protects its own rules (its invariants, such as "balance is never negative").
public class BankAccount {
private final String owner;
private double balance; // hidden
public BankAccount(String owner) { this.owner = owner; }
public String getOwner() { return owner; } // getter
public double getBalance() { return balance; }
public void deposit(double amount) {
if (amount <= 0) throw new IllegalArgumentException("Deposit must be positive");
balance += amount;
}
public void withdraw(double amount) {
if (amount <= 0) throw new IllegalArgumentException("Withdrawal must be positive");
if (amount > balance) throw new IllegalStateException("Insufficient balance");
balance -= amount;
}
}
// account.balance = -50000; // compile error: balance has private accessGetters and setters
By convention (the JavaBeans naming style used by many frameworks), a getter for field price is getPrice() (isActive() for booleans) and a setter is setPrice(value). Do not add a setter for every field automatically. Ask: should outside code really be able to change this? A balance should change only through deposit and withdraw, not setBalance.
public class Employee {
private String name;
private int age;
public String getName() { return name; }
public void setName(String name) {
if (name == null || name.isBlank()) throw new IllegalArgumentException("Name required");
this.name = name.strip();
}
public int getAge() { return age; }
public void setAge(int age) {
if (age < 18 || age > 65) throw new IllegalArgumentException("Age must be 18 to 65");
this.age = age;
}
}Immutable classes
An immutable object can never change after construction: all fields private and final, no setters, and the class itself final so nobody can subclass it and add mutability. String, Integer and LocalDate are immutable. Immutable objects are automatically thread-safe and easy to reason about. To "change" one, you create a new one.
public final class Money {
private final long paise;
public Money(long paise) { this.paise = paise; }
public long paise() { return paise; }
public Money plus(Money other) { return new Money(this.paise + other.paise); } // a new object
}Access modifiers in brief
private: only inside this class. public: from anywhere. Module 5 adds protected and the default (package-private) level. Rule of thumb: fields private, methods public only if other classes need them.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Encapsulation: private fields, getters and setters · 1/6
In this lesson you will protect an object's data with encapsulation.
Prefer a video by a teacher? Find free videos on “java encapsulation private getters setters immutable class” on YouTube ↗
In real life: An order whose status cannot jump around
In a food-delivery backend, an order's status must follow PLACED → PREPARING → OUT_FOR_DELIVERY → DELIVERED. With a public status field, a bug once marked unpaid orders as delivered. With a private field and methods that check the current state, impossible jumps are rejected.
public class Order {
private String status = "PLACED";
public String getStatus() { return status; }
public void startPreparing() { require("PLACED"); status = "PREPARING"; }
public void dispatch() { require("PREPARING"); status = "OUT_FOR_DELIVERY"; }
public void deliver() { require("OUT_FOR_DELIVERY"); status = "DELIVERED"; }
private void require(String expected) {
if (!status.equals(expected)) throw new IllegalStateException("Cannot do this when " + status);
}
}Practice (0/3 done)
class A { private int x; } In another class: A a = new A(); a.x = 5; What happens?
Which getter keeps a private List<String> items safe from outside changes?
Write an encapsulated class Wallet with a private long balancePaise, a constructor, getBalancePaise(), addMoney(long paise) and pay(long paise) that throws IllegalStateException when the balance is too low. Do NOT add setBalance. Show in main that the balance cannot be made negative.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- static members and finalClasses and objects · same module
- ClassesJavaScript Programming (language in depth) · Scope, this, prototypes and classes
- Access modifiers, static members and encapsulationC# and .NET · Classes and objects
- Classes and constructorsFlutter and Dart · Null safety and object-oriented Dart
- Classes and objects: data plus behaviourC++ Programming (modern C++ and DSA) · Classes, constructors and RAII
- Packages and access modifiersInheritance, polymorphism and interfaces
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What is encapsulation?
Answer: Hiding data and exposing behaviour through methods that enforce rules
Objects protect their own state.
The JavaBeans getter name for a boolean field active is…
Answer: isActive()
Boolean getters conventionally start with is.
Which is NOT needed for an immutable class?
Answer: A public no-argument constructor
Immutable classes usually take all values in the constructor.
Why is setBalance(double) a poor design for a bank account?
Answer: It lets callers bypass the deposit/withdraw rules
Behavioural methods enforce the business rules.
What makes a class field private?Related
What is encapsulation?Related
Answer: Hiding an object's data and allowing changes only through controlled members
Encapsulation protects an object's data and rules.
How do you make a field private in Dart?Related
How do you define a member function outside the class?Related
Answer: void BankAccount::deposit(long long p) { }
ClassName:: ties the definition to the class.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 2 more topics in “Classes and objects” before its exam: static members and final, toString, equals, hashCode and records.
- Module 4 exam: Classes and objects · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Inheritance, polymorphism and interfaces. 60 topics left in the course before the final exam.