The <code>protected</code> Access Modifier in Java

protected is the "almost-public" modifier: visible to the same package and to subclasses in other packages. It's the right choice when a class is designed to be extended and wants to expose a controlled set of hooks.

Visibility

  • Same class: βœ…
  • Same package: βœ…
  • Subclass in another package: βœ… β€” but only through the subclass's own instance
  • Unrelated classes in other packages: ❌

Example β€” a template method

package framework;

public abstract class ReportExporter {
    public final void export(Report r) {         // final β€” shape is fixed
        open();
        writeHeader();
        writeBody(r);
        close();
    }
    protected abstract void writeBody(Report r); // subclass plugs in here
    protected void writeHeader() { ... }          // default, overridable
    protected void open() { ... }
    protected void close() { ... }
}

// Subclass in a different package
package app;
import framework.ReportExporter;
public class CsvExporter extends ReportExporter {
    @Override
    protected void writeBody(Report r) { ... }   // βœ… can override
}

Cross-package restriction

public class Sub extends ReportExporter {
    public void demo(ReportExporter other) {
        this.open();           // βœ… own inherited member
        other.open();          // ❌ protected from a different instance, different package
    }
}

Protected fields β€” a smell

A protected field exposes raw state to every subclass, which now couples its implementation to the parent's data layout. Future refactors become painful. Prefer private fields + protected methods β€” subclasses read and write through a controlled interface.

When to use protected

  • Framework-style base classes designed for extension (Spring's AbstractController, JDK's AbstractCollection).
  • Hooks β€” methods a subclass should override but outside code shouldn't call.

When to avoid it

  • Ordinary classes not designed to be extended β€” private or package-private is fine.
  • Fields β€” almost always wrong. Use private + accessors.

Common mistakes

  • Using protected as a looser public β€” if no real subclass will use it, package-private is cleaner.
  • Protected mutable fields β€” subclasses can break invariants.
  • Calling a protected method from an unrelated class β€” compile error.

Related

Pillar: Access modifiers. See also package-private, inheritance.