Access Modifiers

Access modifiers control which parts of your program are allowed to see and use a class, field, method, or constructor. Java has four access levels: public, protected, default (no keyword at all), and private. Choosing the right one is a big part of good encapsulation — hiding the details that outside code doesn't need to know about.

The Four Access Levels

ModifierSame classSame packageSubclass (other package)Everywhere
publicYesYesYesYes
protectedYesYesYesNo
default (no keyword)YesYesNoNo
privateYesNoNoNo
  • public — accessible from any class, in any package. Use it for the parts of your API you want the whole world to call.
  • protected — accessible within the same package, and also from subclasses even if they live in a different package.
  • default / package-private — written by simply leaving the modifier out. Accessible only to other classes in the same package.
  • private — accessible only inside the same class. Not even subclasses can see it.

Applying Modifiers to Classes, Fields, and Methods

A top-level class can only be public or default (package-private) — it can't be protected or private. Fields, methods, and constructors, on the other hand, can use all four levels.

public class Account {
  private double balance; // only this class can touch balance directly
  protected String ownerName; // visible to package + subclasses
  String branchCode; // default: same package only

  public double getBalance() {
    return balance;
  }

  public void deposit(double amount) {
    if (amount > 0) {
      this.balance += amount;
    }
  }
}

Here, balance is private so nobody outside Account can set it directly — they must go through deposit(), which validates the amount first. That's encapsulation in action.

Note: We covered hiding fields behind getters and setters on the Encapsulation page — access modifiers are the mechanism that makes that hiding possible.

When to Use Which

A practical default:

  • Make fields private by default, and expose them through public getters/setters only if outside code actually needs access.
  • Make methods public only if they are meant to be part of the class's external API; keep internal helper methods private.
  • Reach for protected only when you're deliberately designing a class to be extended and want subclasses to reuse certain fields or methods.
  • Leave the default (package-private) level for things that should stay internal to a single package, like helper classes shared between related classes.

A Quick Comparison Table

KeywordTypical use case
publicClass API methods, the class itself if it should be usable from anywhere
protectedMembers meant to be reused or overridden by subclasses
defaultPackage-internal helpers not meant for outside use
privateFields and internal logic that should never be touched from outside the class
Tip: Restricting access as much as possible (start with private, loosen only when needed) makes your classes easier to change later, because you control every place a field or method can be touched from.
Next steps: Next up is the Static Keyword — a modifier that changes who a field or method belongs to, rather than who can see it.