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'sAbstractCollection). - Hooks β methods a subclass should override but outside code shouldn't call.
When to avoid it
- Ordinary classes not designed to be extended β
privateor package-private is fine. - Fields β almost always wrong. Use
private+ accessors.
Common mistakes
- Using
protectedas a looserpublicβ if no real subclass will use it,package-privateis cleaner. - Protected mutable fields β subclasses can break invariants.
- Calling a
protectedmethod from an unrelated class β compile error.
Related
Pillar: Access modifiers. See also package-private, inheritance.