Java Encapsulation and Access Modifiers

Java encapsulation means hiding an object's internal data and exposing only safe ways to use it. You make fields private and provide public methods that control how the data is read and changed.

Private Fields with Getters and Setters

Because balance is private, code outside the class cannot set it to a nonsense value. All changes go through methods that enforce the rules.

class BankAccount {
    private final String owner;
    private double balance;

    BankAccount(String owner) {
        this.owner = owner;
    }

    public double getBalance() {
        return balance;
    }

    public String getOwner() {
        return owner;
    }

    public void deposit(double amount) {
        if (amount <= 0) {
            System.out.println("Deposit must be positive");
            return;
        }
        balance += amount;
    }

    public boolean withdraw(double amount) {
        if (amount > balance) return false;
        balance -= amount;
        return true;
    }
}

public class Main {
    public static void main(String[] args) {
        var acc = new BankAccount("Naeem");
        acc.deposit(500);
        acc.deposit(-20);
        System.out.println(acc.withdraw(800));
        System.out.println(acc.withdraw(150));
        System.out.println(acc.getOwner() + ": " + acc.getBalance());
        // acc.balance = 1_000_000; // compile error: balance has private access
    }
}
Deposit must be positive
false
true
Naeem: 350.0

Java Access Modifiers

  • public: accessible from any class.
  • protected: accessible in the same package and in subclasses.
  • no modifier (package-private): accessible only within the same package.
  • private: accessible only inside the same class.

Why Encapsulation Matters

  • Validation: setters can reject invalid values.
  • Flexibility: you can change how data is stored without breaking other code.
  • Read-only data: provide a getter but no setter, and mark the field final.
  • Easier debugging: every change goes through a few known methods.

Packages and import

Packages group related classes and prevent name clashes. A file starts with a package declaration, and other files use import to refer to its public classes. Standard library classes live in packages such as java.util and java.time.

package com.example.shop;

import java.time.LocalDate;
import java.util.List;

public class Report {
    public static void main(String[] args) {
        List<String> items = List.of("Pen", "Notebook");
        System.out.println(LocalDate.of(2026, 1, 15) + " " + items);
    }
}
2026-01-15 [Pen, Notebook]

Classes in java.lang, such as String, Math and System, are imported automatically. The folder structure must match the package name, so this file belongs in com/example/shop/Report.java.

Frequently asked questions

Why use getters and setters instead of public fields in Java?

They let you validate input, keep fields read-only, and change the internal representation later without breaking code that uses the class.

What is the default access modifier in Java?

With no modifier, a member is package-private: visible to classes in the same package but not outside it.

Should every field have a setter?

No. Only add setters for values that genuinely need to change. Immutable objects with final fields and no setters are simpler and safer.