Introduction
Access modifiers are essential building blocks of Object-Oriented Programming (OOP) in Java. They help control the visibility and accessibility of classes, methods, and variables, promoting encapsulation, modular design, and maintainability. Whether you're designing APIs, structuring enterprise applications, or securing sensitive data, access modifiers play a vital role.
In this tutorial, we'll explore the four access modifiers in Java – public, private, protected, and default (package-private) – and how they shape class interactions in real-world development.
What are Access Modifiers?
Access modifiers in Java define where a class member (field, method, constructor, class) can be accessed from. They enforce encapsulation by restricting or exposing implementation details.
| Modifier | Class | Package | Subclass | World |
|---|---|---|---|---|
| public | ✔ | ✔ | ✔ | ✔ |
| protected | ✔ | ✔ | ✔ | ✘ |
| default | ✔ | ✔ | ✘ | ✘ |
| private | ✔ | ✘ | ✘ | ✘ |
1. public Modifier
Definition
A public class or member is accessible from anywhere – inside the class, package, or even from unrelated classes in other packages.
Syntax
public class Vehicle {
public String type;
public void drive() {
System.out.println("Driving a " + type);
}
}
Use Case
Utility classes, APIs, and constants that are meant to be used across the codebase.
2. private Modifier
Definition
A private member is accessible only within the same class. It is not visible to subclasses or even other classes in the same package.
Syntax
public class BankAccount {
private double balance;
public double getBalance() {
return balance;
}
public void deposit(double amount) {
if (amount > 0) balance += amount;
}
}
Use Case
Encapsulation, data hiding, restricting direct access to sensitive fields.
3. protected Modifier
Definition
A protected member is accessible within the same package and in subclasses (even if they're in different packages).
Syntax
public class Animal {
protected void makeSound() {
System.out.println("Animal makes sound");
}
}
class Dog extends Animal {
public void bark() {
makeSound(); // accessible
}
}
Use Case
Designing frameworks where you want child classes to override or use methods.
4. Default (No Modifier)
Definition
If no modifier is specified, the member is package-private, meaning it's accessible within the same package but not outside.
Syntax
class Product {
int id; // default access
void printId() {
System.out.println("ID: " + id);
}
}
Use Case
Internal implementation details meant for use only within a package.
UML-style Visibility
In UML diagrams:
+denotespublic-denotesprivate#denotesprotected~denotes package-private
Real-world Analogy
Think of access modifiers like house access:
public– Anyone can enter.protected– Only family members or those with a key.default– Only roommates (same package) allowed.private– Only you.
Best Practices
- Start with
privateand loosen restrictions only when needed. - Avoid
protectedunless subclassing is necessary. - Use
publicfor APIs or utility functions only. - Maintain encapsulation by accessing fields through getters/setters.
Version Notes (Java 17/21+)
Java record types implicitly use private final fields with public accessors.
public record Person(String name, int age) { }
Common Mistakes
- Accessing
privatemembers directly from other classes. - Overusing
publicin large codebases – reduces encapsulation. - Misunderstanding
protectedoutside packages.
Refactoring Example
BEFORE
public class User {
public String name;
}
AFTER
public class User {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
Conclusion
Access modifiers are vital for building secure, modular, and maintainable applications. Understanding when and how to use each modifier leads to better OOP design in Java.
✅ Key Takeaways
- Use
privatefor encapsulation. - Use
publicsparingly and only for required external access. protectedgives access to subclasses and same-package classes.- Default is package-private – hidden from external packages.
💬 FAQ
1. Can a top-level class be private in Java?
No, only public or package-private is allowed.
2. Can interfaces have protected methods?
No. All methods in interfaces are public by default.
3. How do access modifiers affect inheritance?
Subclasses can’t access private members, but can access protected ones.
4. Can we override private methods?
No. They are not inherited.
5. What happens if no modifier is used?
It becomes package-private (default access).
6. Are fields in interfaces public?
Yes. Fields in interfaces are implicitly public static final.
7. Can constructors be private?
Yes. Useful in Singleton or Factory patterns.
8. Does protected allow access in unrelated packages?
No. Only subclasses outside the package can access.
9. Can abstract classes have private methods?
Yes. But they won’t be accessible to subclasses.
10. What’s the difference between protected and default?
protected allows subclass access outside the package, default does not.