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
| Modifier | Same class | Same package | Subclass (other package) | Everywhere |
|---|---|---|---|---|
public | Yes | Yes | Yes | Yes |
protected | Yes | Yes | Yes | No |
| default (no keyword) | Yes | Yes | No | No |
private | Yes | No | No | No |
- 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.
When to Use Which
A practical default:
- Make fields
privateby default, and expose them throughpublicgetters/setters only if outside code actually needs access. - Make methods
publiconly if they are meant to be part of the class's external API; keep internal helper methodsprivate. - Reach for
protectedonly 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
| Keyword | Typical use case |
|---|---|
public | Class API methods, the class itself if it should be usable from anywhere |
protected | Members meant to be reused or overridden by subclasses |
| default | Package-internal helpers not meant for outside use |
private | Fields and internal logic that should never be touched from outside the class |
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.