n Java, access modifiers control who can see or use your class members (fields, methods, or constructors).
They’re one of the pillars of encapsulation, helping you protect your code and define clear boundaries between classes.
Let’s break down the three most important ones — public, private, and protected — and when to use each 👇
🧩 What Are Access Modifiers?
Access modifiers define the visibility of a class or its members across your project.
In Java, we mainly use:
public → visible everywhere
private → visible only inside the same class
protected → visible in the same package + subclasses
There’s also default (package-private) when no modifier is specified — visible only inside the same package.
🌍 public: Accessible Everywhere
A public member can be accessed from anywhere — even from another package.
public class Car {
public String brand;
public void start() {
System.out.println("Car started!");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car();
car.brand = "Toyota"; // ✅ Allowed
car.start(); // ✅ Allowed
}
}
✅ When to use:
For methods or classes that need to be used by many other parts of your program (like APIs or utility methods).
When exposing controlled access to other packages.
📘 More: Java public Access Modifier Docs
🔒 private: Hide and Protect
A private member is only accessible inside the same class.
This is the strongest level of protection and a cornerstone of encapsulation.
public class Account {
private double balance;
public void deposit(double amount) {
if (amount > 0)
balance += amount;
}
public double getBalance() {
return balance;
}
}
public class Main {
public static void main(String[] args) {
Account acc = new Account();
// acc.balance = 1000; ❌ Error
acc.deposit(500); // ✅ Allowed
System.out.println(acc.getBalance()); // ✅ 500.0
}
}
✅ When to use:
For sensitive or internal data you don’t want accessed directly.
To maintain control over how values are read or changed (through getters/setters).
📘 More: Encapsulation in Java
🛡 protected: Share with Subclasses
A protected member is accessible:
Inside the same package, and
By subclasses, even if they’re in another package.
class Animal {
protected void makeSound() {
System.out.println("Animal sound");
}
}
class Dog extends Animal {
void bark() {
makeSound(); // ✅ Accessible because Dog extends Animal
System.out.println("Woof!");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.bark();
}
}
✅ When to use:
When designing a class meant to be extended, and you want subclasses to reuse some behaviors safely.
📘 More: Protected Access in Java
⚙️ Summary of Access Levels
Here’s a simple reference you can copy easily:
| Modifier | Same Class | Same Package | Subclass | Outside Package |
|---|---|---|---|---|
public |
✅ | ✅ | ✅ | ✅ |
protected |
✅ | ✅ | ✅ | ❌ |
| default (no modifier) | ✅ | ✅ | ❌ | ❌ |
private |
✅ | ❌ | ❌ | ❌ |
🧠 Why Access Modifiers Matter
They’re not just about restrictions — they’re about control and clarity:
They make your classes safer by preventing accidental misuse.
They help you design cleaner APIs.
They make your code easier to maintain, since you decide what’s exposed and what’s hidden.
💡 Best Practices
Start as restrictive as possible (private) and loosen only when necessary.
Keep fields private — use getters/setters to manage access.
Use protected only for intended inheritance.
Use public for APIs or methods meant for other classes/packages.
🧭 Final Thoughts
Access modifiers are one of Java’s simplest yet most powerful features.
They help you protect your codebase, control visibility, and build robust, maintainable systems.
So next time you write a class, think:
“Who really needs to see this?” 👀
❓Question for You
Do you usually design your classes starting with everything private or open them up as you go?
Share your approach in the comments 👇
Top comments (0)