Do you think IIT Guwahati certified course can help you in your career?
No
Introduction
Java access modifiers define the visibility and accessibility of classes, methods, and variables within a Java program. They control which parts of the code can access certain components. Java provides four main access modifiers: public, private, protected, and default (no modifier). Understanding access modifiers is essential for writing secure, maintainable, and well-structured code.
What are Access Modifiers in Java?
Access modifiers in Java are keywords that define the scope and visibility of classes, methods, variables, and constructors. They control which parts of a program can access specific components. Java provides four types of access modifiers:
Public: Accessible from anywhere in the program.
Private: Accessible only within the declared class.
Protected: Accessible within the same package and by subclasses.
Default (no modifier): Accessible only within the same package.
Access modifiers help enforce encapsulation and improve security in Java applications.
Types of Java Access Modifiers
Based on the extent of an access modifier. There are four types of Java access modifiers
Private: The accessibility of the members of this modifier is such that they are visible to their class only.
Default: The accessibility of the members of this modifier is such that they are visible to their package.
Protected: The accessibility of the members of this modifier is such that they are visible to their packages and subclasses.
Public: The accessibility of the members of this modifier is such that they are visible to the whole world.
The order of restriction of the access modifiers in Java in increasing order of restrictions is public > protected > default > private.
Comparison Table of Access Modifiers in Java
Access Modifier
Within Class
Within Package
Outside package by subclass only
Outside package
Private
Yes
No
No
No
Default
Yes
Yes
No
No
Protected
Yes
Yes
Yes
No
Public
Yes
Yes
Yes
Yes
1. Private Access Modifier
The private access modifier is the most restrictive access modifier in java. Classes and interfaces cannot be declared with a private modifier unless it is a nested class. Methods, functions and variables with the scope of this modifier are accessible only within their particular class. The usage of this modifier is useful to hide data from the outside world.
Let’s understand this with an example.
Example
We create two classes <Alpha> and <Beta> within the same package as follows:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The field Alpha.i is not visible
The method display() from the type Alpha is not visible
at package1.Beta.main(Beta.java:8)
We can see in the above example that accessing the private variable <i> and private method <display()> of the class <Alpha> from the class <Beta> produces a compile-time error. This is because the private keyword sets the accessibility of the members of the class such that they are only accessible within their own class.
2. Default Access Modifier
When you do not specify an access modifier for a class, it is taken to be the default access modifier in Java. No keyword is required to declare the default modifier. The class, method, or function declared with the default access modifier in Java, is accessible to all the other classes within the same package only. Let’s take an example.
Example
We create a class <Alpha> in a package <package1> as follows:
Java
Java
package package1; class Alpha {
//variable with default modifier int i = 5;
//method with default modifier void display() { System.out.println(i); } }
You can also try this code with Online Java Compiler
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
The type Alpha is not visible
The type Alpha is not visible
The type Alpha is not visible
at package2.Beta.main(Beta.java:7)
As we can see, we get a compile-time error if we try to access the class Alpha and method display() from outside their own package. This is because they have been declared with the default access modifier.
3. Protected Access Modifier
The members of this access modifier are accessible by the same package as well as by other packages but only through the means of inheritance. This means that any class or data member declared with the protected keyword will be accessible by the package and subclasses. Let’s understand this with an example. We create two packages <p1> and <p2> with classes <Alpha> and <Beta> respectively. The members of class <Alpha> are inherited in class <Beta>. Therefore, <Beta> is a subclass of <Alpha>.
Example
Java
Java
package p1;
public class Alpha { //protected access modifier method protected void display() { System.out.println(“Protected Method”); } }
package p2; import p1.*;
//inheriting members of Alpha to Beta class Beta extends Alpha {
public static void main(String args[]) {
Beta obj = new Beta();
//prints “Protected Method” obj.display(); } }
You can also try this code with Online Java Compiler
As the output of this code, we get Protected Method printed because the method <display()> is defined with the keyword protected. Hence, giving the subclass of <Alpha>, <Beta>, access to this method.
4. Public Access Modifier
If you are familiar with the basic syntax of Java, you must have seen the following line of code countless times:
public class Main{
The keyword <public> is essentially used to set the scope of this class as the public access modifier in Java. This modifier sets the accessibility to the world i.e. this class can be accessed by any other class, package, subclass, etc.
There are no restrictions on public access modifier members and thus they can be accessed globally. This modifier has the widest scope and maximum visibility among all access modifiers in java.
Let’s understand this using an example. We create two packages <p1> and <p2>, having classes <Alpha> and <Beta> respectively.
Example
Java
Java
package p1; public class Alpha {
//public variable public int i = 5;
//public method public void display() { System.out.println(“Public Method”); } } package p2; import p1.*; class Beta { public static void main(String args[]) {
Alpha obj = new Alpha();
//prints 5 System.out.println(obj.i);
//prints “Public Method” obj.display(); } }
You can also try this code with Online Java Compiler
This code successfully prints 5 and “Public method”. This is because as the class <Beta> is defined with a public access modifier, the variable <i> and the method <display()> are accessible by the world.
Best Practices for Using Access Modifiers in Java with Real-World Examples
Access Modifiers in Java control the visibility and accessibility of classes, methods, and variables. They help enforce encapsulation in Java, ensuring that sensitive data and logic remain protected. Understanding Java access specifiers allows developers to apply proper access control in Java, improving code security and maintainability.
1. Private (Most Restrictive)
Use Case: Used for encapsulation in Java to protect sensitive data within a class.
Scope of Variables in Java: Accessible only within the same class.
Real-World Example:
Bank Account System → A balance variable is private to prevent external modification.
Singleton Pattern → A private constructor restricts object creation outside the class.
Best Practice: Use private for fields and helper methods to prevent direct access from other classes.
2. Default (Package-Private)
Use Case: Allows access within the same package, useful for grouping related classes.
Access Control in Java: No modifier means package-private.
Real-World Example:
Library Management System → Book and Member classes interact within the same package.
Best Practice: Use default access for closely related package-level classes that don’t need outside access.
3. Protected
Use Case: Used for inheritance—accessible within the same package and subclasses.
Scope of Variables in Java: Extends to child classes, even in different packages.
Real-World Example:
Game Development → A Character class has protected attributes like health that subclasses (Warrior, Mage) can modify.
Best Practice: Use protected only for fields or methods meant for subclass customization.
4. Public (Least Restrictive)
Use Case: Allows global access to a class or method. Used for APIs and utilities.
Access Control in Java: Accessible everywhere.
Real-World Example:
REST API Controllers → Public methods handle client requests (public Response getUser()).
Best Practice: Use the public only when necessary, such as for service classes, utility functions, or API endpoints.
Example: Applying Access Modifiers in Java
class BankAccount {
private double balance; // Private: restricts direct access
public BankAccount(double initialBalance) {
this.balance = initialBalance;
}
public double getBalance() { // Public: Allows controlled access
return balance;
}
protected void deductFees(double fee) { // Protected: Accessible in subclasses
balance -= fee;
}
}
// Subclass Example
class SavingsAccount extends BankAccount {
public SavingsAccount(double balance) {
super(balance);
}
public void applyAnnualInterest() {
deductFees(10); // Accessible due to protected modifier
}
}
You can also try this code with Online Java Compiler
Using the right Java access specifiers ensures security, modularity, and maintainability. Following best practices when applying public vs private in Java and other modifiers helps maintain clear access control in Java while optimizing the scope of variables in Java.
Algorithm to Use Access Modifiers in Java
1. Understand the Scope of Each Modifier:
public: Accessible everywhere.
protected: Accessible within the same package and by subclasses.
Default (no modifier): Accessible only within the same package.
private: Accessible only within the declaring class.
2. Determine the Accessibility Requirements:
Decide the visibility of the class, method, or variable based on its role in the program.
Use public for widely shared resources.
Use protected for inheritance-based access.
Use default for package-restricted usage.
Use private for internal implementation details.
3. Apply Modifiers for Classes:
Classes can only be public or default. Decide based on whether the class needs to be accessible outside its package.
4. Apply Modifiers for Methods:
Use public for methods that are part of a public API.
Use protected for methods intended for subclassing.
Use default or private for internal or helper methods.
5. Apply Modifiers for Variables:
Use private for encapsulation to prevent direct access.
Provide controlled access via getter and setter methods.
6. Refactor and Test:
Review your access modifiers to ensure proper encapsulation and maintainability.
Test to confirm no unintended access violations occur.
Why are Access Modifiers Important?
Encapsulation and Data Protection: Access modifiers enforce encapsulation in Java, preventing direct access to sensitive data and maintaining code integrity.
Controlled Access: They restrict or allow access to classes, methods, and variables, ensuring that only authorized components interact with specific code elements.
Enhanced Security: Private access safeguards critical information by making it accessible only within the declaring class, preventing unintended modifications.
Promotes Code Reusability: Public access enables interoperability by allowing classes and methods to be reused across different packages and projects.
Facilitates Inheritance: Protected access supports inheritance, allowing subclasses to access parent class members while keeping them hidden from unrelated classes.
Package-Level Access Control: Default (package-private) access ensures that related classes within the same package can interact while preventing external access.
Examples of Java Access Modifiers
Now that we have looked at each type of access modifier in Java and discussed the scope of each, let us summarise everything through one example, taking inspiration from the official Java documentation (Oracle).
Example Setup
We define two packages:
Package 1: Contains Alpha and Beta classes.
Package 2: Contains AlphaSub (a subclass of Alpha) and Gamma
Let’s look at how the accessibility of the members of the class Alpha changes with different access modifiers.
Access Modifier
Alpha(within class)
Beta (within package)
AlphaSub(outside package by subclass)
Gamma(outside package)
default
Accessible
Accessible
Not Accessible
Not Accessible
private
Accessible
Not Accessible
Not Accessible
Not Accessible
public
Accessible
Accessible
Accessible
Accessible
protected
Accessible
Accessible
Accessible
Not Accessible
This table shows whether a member of the class Alpha is Accessible or Not Accessible by the other classes respectively.
Now that we have a good understanding of the access modifiers in Java, let’s look at the order of accessibility that each modifier offers. It is shown as follows:
public > protected > default > private
Thus, according to this order, one might choose when to give which access level to a data member in Java. For example, if another programmer is using your code, you might want to use the private modifier for restrictive access and avoid the public modifier.
Java Access Modifiers with Method Overriding
Method overriding in Java is a feature that allows the child class to provide a specific implementation of the method that has been declared by one of its parent classes. In simple terms, it refers to overriding the functionality of an existing method.
While performing method overriding using access modifiers, one rule must be followed:
If you are overriding any method, the overridden method (i.e. declared in a subclass) must not be more restrictive.
To follow this, we must keep the restriction order of the access modifiers as we discussed previously, in mind. Recalling the restriction order we know that the public modifier is the least restrictive and the private modifier, the most restrictive.
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Cannot reduce the visibility of the inherited method from Alpha
at p1.Beta.display(Beta.java:5)
at p1.Beta.main(Beta.java:11)
We get a compilation error due to the fact that the default access modifier in Java is more restrictive than the protective modifier, thus disobeying the rule we discussed above.
Frequently Asked Questions
How many modifiers are in Java?
Java has two types of modifiers: access modifiers (public, private, protected, default) and non-access modifiers (static, final, abstract, etc.).
What are access specifiers?
Access specifiers define the visibility of classes, methods, and variables, controlling which parts of the program can access specific components or members.
What is the default specifier in Java?
The default specifier in Java, also known as package-private, is a default access modifier that limits visibility to classes within the same package, ensuring encapsulation while allowing accessibility within a specific scope.
What is the difference between access and non-access modifiers in Java?
Access modifiers are public, private, and protected, that control the accessibility of classes and methods, while non-access modifiers do not control access levels but provide additional functionalities. Non-access modifiers are final, static.
What is the difference between private and protected access modifiers in Java?
The private access modifier restricts access to members within the same class only, while the protected modifier allows access within the same package and to subclasses, even if they are in different packages.
How do access modifiers affect method overloading in Java?
Access modifiers do not affect method overloading in Java, as overloading depends on the method signature (name and parameter list) within the same class. However, the accessibility of overloaded methods is governed by their individual modifiers.
What Are the 12 Modifiers in Java?
Java provides 12 modifiers that control access, behavior, and properties of classes, methods, and variables: public, private, protected, default (no modifier), static, final, synchronized, abstract, native, strictfp, transient, and volatile.
What Is Meant by Access Specifier?
Access Specifiers (Access Modifiers) are keywords in Object-Oriented Programming (OOP) that define the accessibility of classes, methods, constructors, and variables. They control where and how these elements can be accessed within a program. Access specifiers are not a concept but keywords used to enforce data security and encapsulation.
Conclusion
Access modifiers in Java are essential for implementing encapsulation, a core principle of object-oriented programming. They control the visibility of classes, methods, and variables, ensuring secure and organized code. By wisely using public, protected, default, and private, developers can enforce boundaries, protect sensitive data, and promote maintainability.
An area where access modifiers are used is method overriding. The rule to be followed here is that the overridden method (i.e. declared in a subclass) must not be more restrictive.