Introduction
Access Modifiers are keywords used for enforcing encapsulation in Java along with controlling the visibility of the various member functions and properties. They are useful when inheritance is involved as you wouldn't want a child class to be able to access all the methods and properties of the base class.
Thus, to define accessibility, i.e. to determine whether other classes can use a particular field or invoke a particular method in a particular class, we have Access Modifiers in Java.

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 own class only.
- Default: The accessibility of the members of this modifier is such that they are visible to their own package.
- Protected: The accessibility of the members of this modifier is such that they are visible to their own 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.
We will discuss this order in detail in the further sections of this article.
Also see, Swap Function in Java
Java Access Modifiers
Let’s understand the access modifiers in Java better with the help of a table.
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. 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:
class Alpha {
//private variable
private int i = 5;
//private method
private void display() {
System.out.println(i);
}
}
public class Beta {
public static void main(String args[]) {
Alpha obj = new Alpha();
//compile time error
System.out.println(obj.i);
//compile time error
obj.display();
}
}
Output
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:
package package1;
class Alpha {
//variable with default modifier
int i = 5;
//method with default modifier
void display()
{
System.out.println(i);
}
}
Now let’s create another package <package2> with a class <Beta>.
package package2;
import package1.*;
class Beta {
public static void main(String args[]) {
//compile time error
Alpha obj = new Alpha();
//compile time error
obj.display();
}
}
Output -
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.
Read more about, Hashcode Method in Java
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 -
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();
}
}
Output -
Protected Method
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
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();
}
}
Output
5
Public Method
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.
An example to summarise all 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).
We create two packages, package 1 and package 2. In package 1, we have class Alpha and class Beta. In package 2, we have class AlphaSub (which is inherited from class Alpha) and class 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.
Let’s take an example.
class Alpha {
protected void display() {
System.out.println(“Hello World”);
}
}
public class Beta extends Alpha {
void display() {
System.out.println(“Hello World”); //compilation error
}
public static void main(String args[]) {
Beta obj = new Beta();
obj.display();
}
}
Output
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.
Must Read Type Conversion in Java
Frequently Asked Questions
What are the access modifiers in Java?
Access modifiers in Java are used to set the accessibility of a data member. There are four accessibility modifiers – public, private, default, and protected.
What are the 4 types of Java access modifiers?
The four types of Java access modifiers are private, public, default, and protected. Private restricts access to the same class, the public allows unrestricted access to a class, default provides access within the same package, and protected grants access to subclasses in the same package.
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 access modifier and access specifier?
There is no difference between the access modifier and the access specifier. They both mean the same. Both describe the keywords public, private, protected, and default that control the accessibility of classes, methods, and fields in Java.
Conclusion
Often, as a programmer, one feels the need to define the accessibility of certain members of the program. In Java, this is done with the help of access modifiers. The four levels of access modifiers in increasing order of restrictions are public, protected, default, and private.
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.