Access modifiers in Java dictate how classes, methods, and variables are accessed, ensuring proper encapsulation and code security. By understanding public
, private
, protected
, and default (package-private) modifiers, you’ll write cleaner, more maintainable code. This guide breaks down each modifier with examples, a comparison table, and best practices.
Table of Contents
What Are Access Modifiers in Java?
Access modifiers define the scope of classes, methods, and variables. They enforce encapsulation by restricting unwanted access and exposing only necessary components. Java has four access levels:
public
: Accessible everywhere.private
: Accessible only within the same class.protected
: Accessible within the same package and subclasses (even in different packages).- Default (no modifier): Accessible only within the same package.
Access Modifiers Comparison Table
Modifier | Same Class | Same Package | Subclass (Same Pkg) | Subclass (Diff Pkg) | Any Class (Diff Pkg) |
---|---|---|---|---|---|
public | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
protected | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No |
Default | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No | ❌ No |
private | ✅ Yes | ❌ No | ❌ No | ❌ No | ❌ No |
1. public
Modifier
Visibility: Everywhere.
Use public
for classes/methods that form your API.
Example:
public class Animal {
public String name;
public void eat() {
System.out.println("Eating...");
}
}
// In another package:
public class Test {
public static void main(String[] args) {
Animal cat = new Animal();
cat.name = "Whiskers"; // Accessible
cat.eat(); // Accessible
}
}
2. private
Modifier
Visibility: Same class only.
Use private
to enforce encapsulation and hide implementation details.
Example:
public class BankAccount {
private double balance; // Hidden from external access
public void deposit(double amount) {
if (amount > 0) balance += amount; // Controlled modification
}
public double getBalance() {
return balance; // Read-only access
}
}
3. protected
Modifier
Visibility: Same package + subclasses (even in different packages).
Use protected
to allow subclass customization.
Example:
package com.codersathi.vehicles;
public class Vehicle {
protected String engineType;
protected void startEngine() {
System.out.println("Engine started");
}
}
// Subclass in a different package:
package com.codersathi.cars;
import com.codersathi.vehicles.Vehicle;
public class Car extends Vehicle {
public void drive() {
engineType = "V8"; // Accessible via inheritance
startEngine(); // Accessible via inheritance
}
}
4. Default (Package-Private) Modifier
Visibility: Same package only.
Use default for package-specific utilities.
Example:
package com.codersathi.utils;
class Logger { // Default access
void log(String message) {
System.out.println(message);
}
}
public class App {
public static void main(String[] args) {
Logger logger = new Logger(); // Accessible (same package)
logger.log("Hello World");
}
}
// Class in another package cannot access Logger.
Common Mistakes and Fixes
1. Overusing public
:
- Risk: Exposes internal logic to unintended modifications.
- Fix: Use
private
for variables and provide controlled access via methods.
2. Misunderstanding protected
:
- Myth: Protected members are accessible to any class in a different package.
- Reality: Only accessible to subclasses in different packages.
3. Ignoring Default Scope:
- Risk: Accidentally exposing package-specific classes/methods.
- Fix: Explicitly use
public
orprivate
unless package access is intentional.
Best Practices
- Encapsulate Data: Declare variables
private
and usepublic
getters/setters. - Limit
public
Exposure: Only expose methods critical to your API. - Use
protected
Judiciously: For methods/variables meant for subclass extension. - Leverage Default for Utilities: Hide package-specific helper classes.
Conclusion
Access modifiers in Java are essential for building secure, modular applications. By mastering public
, private
, protected
, and default, you’ll enforce encapsulation, reduce bugs, and design robust APIs.
FAQs
Can a top-level class be private
or protected
?
No. Top-level classes can only be public
or default (package-private).
How do access modifiers affect method overriding?
Overriding methods cannot have a more restrictive access modifier.
Superclass: protected
→ Subclass: public
/protected
(allowed).
Superclass: public
→ Subclass: private
(error).
Can local variables have access modifiers?
No. Access modifiers apply only to class members (fields, methods, nested classes).