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
private
and loosen restrictions only when needed. - Avoid
protected
unless subclassing is necessary. - Use
public
for 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
private
members directly from other classes. - Overusing
public
in large codebases – reduces encapsulation. - Misunderstanding
protected
outside 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
private
for encapsulation. - Use
public
sparingly and only for required external access. protected
gives 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.