Access Modifiers in Java with Examples

In this tutorial, we will learn about access modifiers in Java with the help of examples. Before understanding access modifiers, let us first understand what a modifier is in Java.

A modifier in Java is a keyword that we add to those definitions that we need to change their meaning. In other words, a modifier limits the visibility of classes, fields, constructors, or methods in the Java program.

The functionality of members of a class or a class itself can be protected from other parts of the program by the presence or absence of modifiers.

Java language provides a total of 12 modifiers. They are:

  • public
  • private
  • protected
  • default
  • final
  • synchronized
  • abstract
  • native
  • strictfp
  • transient
  • volatile

These twelve modifiers in Java are broadly divided into two categories:

  • Access modifiers
  • Non-access modifiers

In this tutorial, we will focus only on access modifiers with the help of some important examples. In the next tutorial, we will cover non-access modifiers in Java.

Two types of modifiers in Java: access nodifiers and non-access modifiers

Access Modifiers in Java


Access modifiers (also known as access specifiers) in Java define the scope or boundary for accessing members of a class and a class itself. In other words, access modifiers are those modifiers that are used to restrict the visibility (accessibility) of classes, fields, methods, or constructors.

In short, the accessibility/visibility of data and methods depends on the access modifiers applied to them. The access modifiers are also known as visibility modifiers. Access modifiers help implement data hiding and encapsulation by restricting unauthorized access to class members.

Java provides four explicit access modifiers:

  • private
  • default (package-private)
  • protected
  • public

These access levels control where you can access a class or its members within a program, as shown in the figure below.

Types of access modifiers in Java: private, default, protected, and public.

Private Access Modifier in Java


There are the following important points about private access modifiers in Java that need to be kept in mind.

  1. The private access modifier can be applied to fields (instance variables), methods, constructors, and nested (inner) classes. However, you cannot apply it to a top-level class or interface.
  2. You can declare instance variables and class variables (static variables) as private, but you cannot apply access modifiers to local variables. This is because you can access them only within the method, constructor, or block in which you declare them.
  3. Private members (fields, methods, or constructors) of a class cannot be accessed directly from outside the class. They are accessible only within the same class.
  4. Private members of a superclass cannot be inherited to the subclass. Therefore, they are not accessible directly in a subclass.
  5. If you make any constructor as private in the class, you cannot create an object of that class from another class and also cannot create the subclass of that class.
  6. A top-level class cannot be private except for inner classes. Inner classes are members of the outer class. So, the members of the outer class can be private.
  7. A private method cannot be overridden because it is not inherited by subclasses. Although a subclass may declare a method with the same name and signature, it is considered a new method, not an overridden one.

Example 1: Accessing Private Members from Another Class

Let us consider an example program in which we create two classes: Class A and Class B. In Class A, we declare a field and a method as private. When we try to access the private field and private method of Class A from Class B, the compiler generates a compile-time error because private members are accessible only within the class in which they are declared.

class A // Here, class is default with no access modifier. 
{ 
// Declaration of an instance variable. 
   private int data = 30; // Here, instance variable is private. 

// Declaration of an instance method. 
   private void msg() // Here, method is also private. 
   { 
     System.out.println("Hello Java, this is my first java program"); 
   } 
}

Now, create another class B and call private the field and method of class A.

public class B 
{ 
// Main method.
   public static void main(String[] args) 
   { 
   // Create an object of class A and call members of class A using reference variable 'a'. 
      A a = new A(); // a is a reference variable of class A and pointing to the objects of class A. 
   
   // This statement will generate compile time error.
   // Because we cannot call private members of any class directly from outside the class.
      System.out.println(a.data): 

   // This statement will also generate a compile time error. 
   // So, we cannot call the private method of any class because this is accessible within the class only.
      a.msg(); 
 }
}

Role of Private Constructor in Java


If we declare a constructor of a class as private, we cannot create an object of that class from outside the class because the constructor is inaccessible.

If a class contains only private constructors, we cannot instantiate it from another class. Such a class also cannot be extended because a subclass cannot access the private constructor of its superclass.

Example 2: Private Constructor in Java

Let us take an example program in which we declare a constructor as private and then try to create an object of that class from another class. Since the constructor is private, the compiler generates a compile-time error.

class A 
{ 
// Declaration of constructor. 
   private A() // Here, Constructor is declared as private. 
   { 
     System.out.println("Constructor is private"); 
   } 
// Declaration of an instance method. 
   private void msg() // Here, method is private. 
   { 
      System.out.println("Method is private"); 
   } 
}

Now, create another class B and call class A from class B. As you will call class A, the compiler will generate the compile-time error.

public class B 
{ 
// Main method. 
   public static void main(String args[]) 
   { 
 //  Create the object of class A.
  // This statement will produce a compile time error.
  // Because the constructor is private and we cannot create the object of class A from outside the class.  
     A a = new A(); 
  }
}

Q. Can you find the error in the code?

private class Student
{
 private int roll = 4;
 private class Name
 {
   // Inner class 
 }
}

Answer: Outer class cannot be private but inner class can be private. Instance variable can be private. The outer class is also known as top-level class. The only five modifiers are applicable to a top-level class. They are public, default, final, abstract, and strictfp.

By mistake, if you will try to use any other modifiers with top-level class, you will get a compile-time error: “Modifier private not allowed here”.

For more details, read this: Private Constructor in Java

Default Access Modifier in Java


There are the following important points about default access modifiers in Java:

  1. When no access modifier is specified for a class, field, method, or constructor, Java assigns the default access level, also known as package-private access.
  2. Default access can apply to fields (instance variables and static variables), methods, constructors, and classes (top-level and nested classes). However, local variables cannot have access modifiers.
  3. Members with default access are accessible within the same class and by all other classes in the same package. However, they cannot be accessed from classes in a different package.
  4. A subclass can access inherited default members only if it belongs to the same package as the superclass. A subclass in a different package cannot access default members.

Example 3: Default Access Modifier in Java

Let us consider an example where we create two packages, pack1 and pack2. We have declared Class A with default access (no access modifier). When we try to access Class A from a class in package pack2, the compiler generates a compile-time error because a class with default access is accessible only within its own package.

package pack1; 
class Student 
{ 
// Declaration of an instance variable. 
   int roll = 12; // Here, instance variable is default. 
 
// Declare the method. 
   void name() // Here, method has been defined with default access modifier. 
   { 
      System.out.println(" Hello Java"); 
   } 
 }
package pack2; 
import pack1.*; 
class College 
{ 
// Main method. 
  public static void main(String[] args) 
  { 
// Creating an object of class Student from package pack2. 
// This statement will generate a compile time error 
// because class Student has been defined with default access modifier. 
// So, we cannot be instantiated it from outside the package. 
// But, if it is declared as public, then we can instantiate from outside the package.
   
   Student obj = new Student();  
   obj.name(); // Compile time error because of the default access modifier.
  }
}

Protected Access Modifier in Java


There are the following key points about protected access modifiers in Java:

  1. The protected access modifier can be applied to fields (instance variables and static variables), constructors, methods, and nested (inner) classes. However, it cannot be applied to local variables or top-level classes.
  2. Protected members are accessible:
    • Within the same class,
    • By all classes in the same package, and
    • By subclasses in different packages through inheritance.
  3. Protected members are inherited by subclasses, provided the inheritance rules are satisfied.
  4. If you declare a constructor as protected, you can access it within classes in the same package and within subclasses, even if they are located in a different package.

Example 4: Protected Access Modifier in Java

Let us take an example program to understand the concept of the protected access modifier. In this example, we create two packages, pack1 and pack2. The Student class in pack1 is declared as public, so classes outside the package can access it.

However, the name() method is declared as protected. Therefore, classes in other packages cannot access it directly through an object reference. They can access it only through inheritance by creating a subclass of Student.

package pack1; 
public class Student 
{ 
// Declaration of an instance variable. 
   int roll = 12; // Here, instance variable is default. 
   protected void name() // Here, method has been defined with protected access modifier. 
   { 
     System.out.println("My roll no. is 12"); 
   } 
}
package pack2; 
import pack1.*; 
class College extends Student { 
public static void main(String args[]) 
{ 
// Creating the object of class Student from pack2. 
   Student obj = new Student(); // Calling the method using reference variable obj. 
   obj.name(); 
  } 
}

Output:

My roll no. is 12.

Public Access Modifier in Java


The following are key points about the public access modifier in Java:

  1. The public access modifier can be applicable to fields, methods, constructors, interfaces, enums, records, and both top-level and nested classes. However, you cannot apply it to local variables.
  2. Public members of a class are accessible from anywhere in the program, provided the class itself is accessible.
  3. Public members are inherited by subclasses, regardless of whether the subclass is in the same package or a different package.

Example 5: Public Access Modifier in Java

Let us take an example program to understand the public access modifier. In this example, we have declared the Student class as public and also declared the name() method as public. Therefore, we can create an object of the Student class in another package and invoke the name() method without any access restrictions.

package pack1; 
public class Student 
{ 
  int roll = 12; // Here, instance variable is default. 
  public void name() // Here, method has been defined with protected access modifier. 
  { 
    System.out.println(" My roll no. is 12"); 
  } 
}
package pack2; 
import pack1.*; 
class College extends Student 
{ 
  public static void main(String args[]) 
  { 
// Creating the object of class Student from pack2. 
     Student obj = new Student(); 
      obj.name(); 
   } 
}

Output:

My roll no. is 12

Visibility of Access Modifiers in Java


The below table summarizes the visibility of various access modifiers in Java.

Access locationPublicProtectedDefaultPrivate
Same classYesYesYesYes
Subclass in same packageYesYesYesNo
Other classes in same packageYesYesYesNo
Subclasses in other packageYesYesNoNo
Non-subclasses in other packagesYesNoNoNo

Key of Access modifiers:

Private  >  Default  >  Protected  >  Public
More restrictive ----------------> Less restrictive.                                        
                    Decreasing

Applicable Modifiers with Classes, Methods, Variables, Interfaces


Outer Class (Top-level Class)

  • The modifiers applicable to a top-level class are: public, default (no modifier), final, abstract, and strictfp.
  • A class cannot be declared as both final and abstract because these modifiers have opposite meanings.
  • A top-level class cannot be declared as private or protected.

Inner Class

  • The modifiers applicable to a nested (inner) class are public, protected, private, default, static, final, abstract, and strictfp.
  • The modifiers synchronized, native, transient, and volatile are not applicable to inner classes.
  • The modifiers applicable to inner classes but not to top-level classes are private, protected, and static.

Methods

  • The modifiers applicable to methods are:
    • public
    • protected
    • private
    • default
    • final
    • abstract
    • static
    • synchronized
    • native
    • strictfp
  • The modifiers transient and volatile are not applicable to methods.
  • An abstract method cannot be declared as:
    • final
    • static
    • synchronized
    • native
    • private
  • Since Java 17, strictfp has no practical effect. Although the keyword still exists, combining abstract and strictfp is permitted by modern Java compilers.

Variables

  • The modifiers applicable to fields are:
    • public
    • protected
    • private
    • default
    • final
    • static
    • transient
    • volatile
  • The modifiers abstract, synchronized, native, and strictfp are not applicable to variables.
  • Local variables can be declared as final.

Constructors

  • For a constructor in Java, only access modifiers are applicable. The access modifiers like public, protected, default, and private can be applied with constructors.
  • Non-access modifiers cannot be applied with constructors. By mistake, if you apply any other modifiers with constructor except these four access modifiers, you will get a compile-time error.

Blocks

  • Static modifier are only applicable for blocks.

Top-Level Interface

  • Public, default, abstract, and strictfp are modifiers that are applicable for top-level interface. Except for these modifiers, you cannot apply other modifiers with outer or top-level interface.
  • The final keyword is not applicable for an interface in Java.

Inner Interface

  • For inner interface, you can apply modifiers like private, default, protected, public, abstract, static, and strictfp.
  • The non-access modifiers such as final, synchronized, native, transient, and volatile are not applicable for inner interface.

Outer Enum

  • The only three modifiers like public, default, and strictfp are applicable for outer enum.
  • The modifiers which are applicable for classes, but not applicable for enum are final and abstract.

Inner Enum

  • For inner enum, we can apply all four access modifiers and two non-access modifiers like static, and strictfp.
  • The modifiers abstract, final, synchronized, native, transient, and volatile are not applicable to inner enum.

Conclusion

Understanding and correctly applying access modifiers in Java is essential to control the visibility and accessibility of the class, method, or field from the other sections of the code or other programs.

We use them before a class, method, or field declaration. Always remember that only two access modifiers are applicable to top-level classes. However, inner classes can also private or protected.

DEEPAK GUPTA

DEEPAK GUPTA

Deepak Gupta is the Founder of Scientech Easy, a Full Stack Developer, and a passionate coding educator with 8+ years of professional experience in Java, Python, web development, and core computer science subjects. With strong expertise in full-stack development, he provides hands-on training in programming languages and in-demand technologies at the Scientech Easy Institute, Dhanbad.

He regularly publishes in-depth tutorials, practical coding examples, and high-quality learning resources for both beginners and working professionals. Every article is carefully researched, technically reviewed, and regularly updated to ensure accuracy, clarity, and real-world relevance, helping learners build job-ready skills with confidence.