In this post, you will learn to:

  • State the purpose of access modifiers.
  • Identify the use of public access specifier.
  • State the purpose of private access specifier.
  • State the use of protected access specifier.
  • State the use of default or package access specifier.
  • List the rules for using access specifiers.

Access Modifiers

Access specifiers or modifiers are used to control the access of classes and class members. The access specifiers also determine whether classes and the members of the classes can be invoked by other classes or interfaces.

There are four levels of access in Java:

  • public
  • private
  • protected
  • default or package access

Object-oriented principles are implemented in programs through the use of access specifiers. Access control helps to prevent misuse of class details as well as hides the implementation details that are not required by other programmers. If a class or its member is allowed access, it is said to be accessible. Accessibility affects inheritance and how members are inherited by the subclass.

The table below shows the relationship between access specifiers and various elements in a Java program.

Java Access specifiers for Various Elements

Thus, as seen in table above, top level classes and interfaces can have public or default access specifier. Data fields, constructors, and methods can have any one of the four access modifiers. Local variables defined inside methods are not given any access specifiers. Only class-level variables, also known as instance variables, can have access specifiers.

Note: A package is always accessible by default.

Using ‘public’ with Classes

The public access specifier when applied to a Java class allows the class to be accessible everywhere,even outside its package. The following code demonstrates the declaration of class, Employee with public access specifier.

Program1: Employee.java

package firm;
public class Employee {
public Employee() {
    System.out.println("Constructor of Employee");
    }
}

The following code creates an object of class, Employee in another class, Accountant.

Program 2: Accountant.java

class Accountant {
public static void main(String args[]) {
    firm.Employee e = new firm.Employee();
    }
}

In this example, Employee is declared as a public class in a package named firm. Since it is public, it is accessible everywhere. This is demonstrated by creating an object of type Employee in a class named Accountant which is not part of the same package. If the class Employee was not declared as public in this example, it would not have been accessible in the Accountant class.

Using ‘public’ with Members

The public access specifier, when applied to any member of the class allows the member to be accessible from anywhere in a program. The following code demonstrates the declaration of members with public access specifier in class, Employee.

Program 1: Employee.java

package firm;
public class Employee {
public int empId;
public Employee(){
empId = 0;
}
public void displayId(){
    System.out.println("The Employee's id is " + empId);
    }
}

The following code access the public members of the class, Employee in another class, Accountant.

Program 2: Accountant.java

import java.util.*;
class Accountant {
public static void main(String args[]) {
    firm.Employee emp = new firm.Employee();
    System.out.println("Enter employee id"); 
    Scanner scn = new Scanner(System.in);
    emp.empId = scn.nextInt();
    emp.displayId();
    }
}

In this example, empId, Employee(), and displayID() are declared as public members of Employee class. Thus these members can be invoked from another class named Accountant.

Using ‘private’ with Members

Data encapsulation is implemented using data hiding, which is a feature of the object-oriented (OO) approach and Java being an OO language, supports this feature through the use of the private access specifier.

When a class or its member is declared with a private access specifier, it is accessible only within its own class and not from anywhere else. The member becomes inaccessible to other classes. Typically, data that is sensitive and important and that which must not be changed in any way by others is declared as private.

The following code demonstrates the declaration of class, PayRoll and its members with private access specifier.

package company;
// class declaration
private class PayRoll {
// member variable
private int employeeId;  //employee identification number 
private int netSalary;   //net salary
// constructor
private PayRoll(int employeeId, int netSalary ) {
   //private fields can be used inside method
   this.employeeId = employeeId; 
   this.netSalary = netSalary;
   }
// member method
private int getEmployeeId(){
    return employeeId;
   } 
}

In this code, since the class has been declared as private, it is not accessible from outside the package.There must be another public class in the same package with the private class. The member variables employeeId and netSalary are declared as private. These member variables can be used by methods in the same class, but not from outside the class.

The method getEmployeeId() is a private method and is not accessible from outside the class. Since, the constructor has been declared as private, it will not allow the creation of class instances, because it is inaccessible. In practice, constructors are rarely declared as private.

Using ‘protected’ with Members

When a class member is declared with a protected access specifier, it is accessible only within its own class and the inheriting classes. The protected access specifier acts like private access specifier,except for the subclasses. The following code demonstrates the declaration of members as protected in class, PayRoll.

Program 1: PayRoll.java

package firm;
// Declaring class
public class PayRoll {
// constructor
protected PayRoll() { }
// member variables
protected int employeeId;   //employee identification number
private int netSalary;   //net salary
// member methods
protected PayRoll(int employeeId, int netSalary ) {
   this.employeeId = employeeId;
   this.netSalary = netSalary;
   }
}

In this code, the member variable employeeId has been declared as protected which means it can be used in PayRoll class and it’s inheriting classes. PayRoll is created inside the package firm.

Default or Package Access

If no modifier is specified for a class, the package access is the default access. This means that the class can be accessed by any other class in the same package. Likewise if a class member has no modifier, the member will be considered to have package access,which is again the default access. Classes outside the package will not be able to invoke any of the members. The following code demonstrates the behavior of default access specifier.

package firm;
// Class declaration with package access
class Pay {
   // Member variable declaration with package access 
   int employeeId; //employee identification number
   int netSalary; //net salary
   // Constructor with package access
   Pay() {
   
   }
   //member method with package access
   int getemployeeId(){
   return employeeId;
   }
}
public class Bonus {
    public static void main(String args[]){
    firm.Pay p = new firm.Pay();
    System.out.println("in Bonus"); 
   }
}

In this code, the class Pay, its member variables and methods have not been given any access modifiers. The package access is therefore default and can be used in any class within the same package. The class Bonus makes use of the class, Pay.

The table below summarizes the access specifier with their visibility within the same package and outside it.

Java Access Specifiers and their Scope

Rules

Java has rules and constraints for usage of access control and they are as follows:

While declaring members, a private access specifier cannot be used with abstract, but it can be used with final or static.

  • No modifier can be repeated twice in a single declaration.
  • A constructor when declared private will be accessible in the class where it was created.
  • A constructor when declared protected will be accessible within the class where it was created and in the inheriting classes.
Introduction to Java Packages
Java Field and Method Modifiers