🏗️ Classes & Objects · Intermediate

Access modifiers in Java

public, protected, package-private (default), private.

🧩 The mysteryYour class is public, so everyone can read its fields... right? Wrong — and that surprise is one of Java's best features.

Four doors

Think of a house. **public: the front door, anyone can come in. protected: family and close neighbors. No modifier (package-private): people on your street — same package. private**: your diary, only inside the class itself.

Most open to most closed

The order is public > protected > package-private > private. Package-private has no keyword — writing nothing *is* the choice. (static and final aren't access modifiers, and internal is Kotlin, not Java.)

public    int a; // everyone
protected int b; // package + subclasses
          int c; // package only
private   int d; // this class only

protected is wider than it sounds

protected = everything package-private allows, plus subclasses in other packages. So any class in the same package can use a protected member — even one that isn't a subclass.

🤔 Think first

public class = public fields?

public class Item { int stock; } — can code in another package read stock?

Think about it, then reveal the answer

No. The class's modifier and each member's modifier are separate decisions. stock has no modifier, so it's package-private: visible only inside Item's own package, even though Item itself is public.

⚠️ The trap

The invisible field

Two files, two packages. Item is public, but stock isn't — so Main doesn't compile.

// shop/Item.java
package shop;
public class Item {
    int stock;      // package-private
}
// app/Main.java
new shop.Item().stock = 3; // error!
🔮 Predict it

Quick check

Which level is more open?

  1. protected
  2. package-private
  3. They are equal
Show the answer

protected. It includes all of package-private's access and adds subclasses in other packages.

💼 In the real world

In real projects

In a library, everything public becomes a promise — users depend on it, and removing it breaks them. Experienced developers start every member as private and open it up only when needed ("minimize accessibility", a classic Effective Java rule).

Key takeaways

  1. public > protected > package-private > private
  2. No keyword = package-private (same package only)
  3. protected = same package + subclasses
  4. Each member's own modifier decides its visibility
🤯 Did you know?

private works per class, not per object: a method can read the private fields of another object of the same class — that's how equals can compare other.balance.

Practice questions

Fill the blank to complete the order from most open to most restrictive.

public
protected
___
private
  1. package-private (no modifier)
  2. static
  3. final
  4. internal
Check your answer

package-private (no modifier). Java has four access levels. package-private sits between protected and private. static and final are not access modifiers, and internal is Kotlin, not Java.

Two files in different packages. Does Main compile?

// shop/Item.java
package shop;
public class Item {
    int stock;
}
// app/Main.java
new shop.Item().stock = 3;
  1. No: stock is package-private, so it is invisible outside package shop
  2. Yes: Item is public, so all its fields are public too
  3. Yes, but it throws IllegalAccessError at runtime
  4. Yes, with a warning
Check your answer

No: stock is package-private, so it is invisible outside package shop. A class's modifier and its members' modifiers are separate. stock has no modifier, so only code in package shop can access it.

Next: private fields plus smart methods make an object nobody can break. That's encapsulation.