Java Tutorial Series: This lesson is part of our comprehensive Complete Java Tutorial: Learn Java from Beginner to Advanced.
This guide explains the topic from beginner level through practical Java development, common mistakes, debugging, design considerations, examples, and practice. The goal is to understand not only the syntax, but when and why the feature should be used in a real Java project.
What Are Access Modifiers?
Access modifiers control where classes and members can be used. They are a major part of encapsulation and API design.
public
public provides broad access wherever the containing type is accessible. Public methods often form the intended API of a class.
public class User {
public void login() { System.out.println("Login"); }
}
private
private members are accessible only within their declaring class. Private fields are commonly used to protect state.
class Account {
private double balance;
public double getBalance() { return balance; }
}
protected
protected provides access within the same package and has additional access rules for subclasses, including across packages. It should not be simplified to “public to subclasses.”
Package-Private
No modifier means package-private access in relevant contexts. It can expose implementation details to collaborating classes in the same package without making them public.
Encapsulation
Keeping fields private and exposing controlled behavior lets a class enforce invariants.
class BankAccount {
private double balance;
public void deposit(double amount) {
if (amount > 0) balance += amount;
}
}
Constructors and Access
Constructors can be private, protected, package-private, or public depending on the design. A private constructor can restrict direct object creation and support factory-style designs.
class Utility {
private Utility() {}
}
Top-Level Types
Ordinary top-level classes are public or package-private. private and protected are member-level access modifiers rather than modifiers for ordinary top-level classes.
Inheritance and Access
A subclass does not automatically gain access to every parent member. Private state remains encapsulated in its declaring class, while protected has specific package and subclass rules.
Best Practices
- Start with the narrowest visibility that works
- Keep mutable fields private
- Expose behavior rather than raw state
- Use package-private deliberately
- Keep public APIs small
Practice
Create a class demonstrating each access level. Build a private field with validation. Test package-private access from the same package. Create a subclass and examine protected access.
Frequently Asked Questions
What is private?
Access limited to the declaring class.
What is package-private?
Access available within the same package when no explicit modifier is used.
Why keep fields private?
To protect state and control how it changes.
Conclusion
Mastering this topic gives you a stronger foundation for multi-file Java programs and professional development. Focus on understanding the concept, writing small examples yourself, testing edge cases, and recognizing how the feature fits into larger application structure.
Learn More
- Java classes and objects
- Java data structures
- Java exception handling
- Java project structure
- Java testing and debugging
- Java application development
Continue Learning Java
Continue through the Java path: methods → parameters and arguments → overloading → scope and variables → packages → imports → access modifiers → classpath and project structure. These concepts prepare you for object-oriented programming and larger Java applications.
Extended Practice
- Write the main example without copying it.
- Change inputs and test normal, boundary, and invalid cases.
- Explain the execution flow in your own words.
- Refactor one example to make its responsibility clearer.
- Explain where the concept appears in a real Java application.