1. Understanding Java Access Modifiers

When developing a Java class, it becomes essential to define how that class interacts with the rest of the Java Virtual Machine (JVM). The concept of access modifiers comes into play, allowing developers to precisely control the visibility and accessibility of their classes. Access modifiers are crucial in shaping how other parts of the program can interact with the class, including its methods, variables, and other components.

In Java, there are four main access modifiers that play a pivotal role in determining the accessibility of classes, interfaces, variables, methods, constructors, data members, and setter methods. Let's delve into each of these access modifiers:

1. Public:

public class MyClass {
  // Class implementation
}

2. Default (Package-Private):

class MyDefaultClass {
  // Class implementation
}

3. Private:

private class MyPrivateClass {
  // Class implementation
}

4. Protected:

protected class MyProtectedClass {
  // Class implementation
}

Understanding and appropriately utilizing these access modifiers is fundamental in designing Java classes with encapsulation, ensuring a robust and maintainable codebase. Each access level serves a specific purpose, offering developers the flexibility to control the visibility of their components based on the desired level of encapsulation.

Understanding Java Access Modifiers

2. Understanding Public Access Modifier in Java

In Java, the public access modifier plays a crucial role in determining the accessibility of classes, methods, or variables. When a class is declared as public, it signifies that the class can be accessed from anywhere in the program. The public keyword can be applied to classes, methods, or variables, providing flexibility in defining the scope of accessibility.

2.1 Example – Public Class

Let's delve into an example to illustrate the usage of the public access modifier. Consider two Java files, A.java and B.java, residing in different packages (pack1 and pack2). Both class A and class B are declared as public. In this scenario, class B in pack2 accesses class A from pack1 to create an object of class A.

Code: A.java

package pack1;
public class A {
}

Code: B.java

package pack2;
import pack1.A;
public class B {
  public static void main(String[] args) {
    A a = new A();
  }
}

Upon compiling and executing the code, we observe that there is no error, indicating the successful creation of the object. The illustration below depicts how the accessibility is possible when class A is declared as public.

Understanding Java Access Modifiers

2.2 Example – Public Method

Now, let's explore an example involving a public method within class A. In this scenario, class A in pack1 contains a public method, m1. class B in pack2 creates an object of class A and invokes the m1 method. The code for class A and class B is as follows:

Code: A.java

package pack1;
public class A {
  public void m1() {
    System.out.println("A class method");
  }
}

Code: B.java

package pack2;
import pack1.A;
public class B {
  public static void main(String[] args) {
    A a = new A();
    a.m1();
  }
}

Upon compiling and executing the code, we again observe no errors, indicating successful execution. The diagram below illustrates how the accessibility is possible for this case when both class A and method m1 are declared as public.

Understanding Java Access Modifiers

3. Understanding Default Access Modifier in Java

The default access modifier in Java restricts the accessibility of classes, methods, or variables to within the same package. This means that entities with default access can only be accessed and utilized within the package they are defined in. The default keyword can be applied to classes, methods, or variables to set their access level.

3.1 Example – Creating Object and Accessing Method in the Same Package using Default Access Modifier

In this example, we create a Java file named MyMain.java. Inside this file, there are three classes: A, B, and MyMain, all with default access modifiers. Class A contains a default method m1, and class B contains a default method m2. In the main method of MyMain, we create objects of class A and class B, calling m1 from class A and m2 from class B.

//Code: MyMain.java
package pack1;
class A {
  void m1(){
    System.out.println("This is m1");
  }
}
class B {
  void m2(){
    System.out.println("This is m2");
  }
}
class MyMain {
  public static void main (String[] args){
    A a = new A();
    B b = new B();
    a.m1();
    b.m2();
  }
}

Upon compilation, the absence of errors indicates the successful execution of the code. The diagram illustrates that all access activities occur within the package, ensuring smooth execution.

Understanding Java Access Modifiers

3.2 Example - Accessing Default Method in Default Class from Different Package

In this example, we create two Java files, A.java and B.java, residing in different packages (pack1 and pack2). Class A has a default access level and contains a default method m1. We attempt to create an object of class A in class B and call m1. However, there are errors during compilation, indicating the inaccessibility of default access members from outside the package.

//Code: A.java
package pack1;
class A {
  void m1(){
    System.out.println("A class method");
  }
}
//Code: B.java
package pack2;
import pack1.A;
public class B{
  public static void main (String[] args){
    A a = new A();
    a.m1();
  }
}

The diagram illustrates the inaccessibility of class A with a default access modifier from outside its package, resulting in compilation errors.

Understanding Java Access Modifiers

3.3 Example - Default Method in Public Class

In this example, we showcase a scenario where a method is declared as default in a class that is public. Two Java files, A.java and B.java, reside in different packages (pack1 and pack2). Class A is declared as public, and it contains a default method m1. An attempt to create an object of class A in class B and call m1 results in compilation errors.

//Code: A.java
package pack1;
public class A {
  void m1(){
    System.out.println("A class method");
  }
}
//Code: B.java
package pack2;
import pack1.A;
public class B{
  public static void main (String[] args){
    A a = new A();
    a.m1();
  }
}

The diagram illustrates the inaccessibility of a default method within a public class from outside its package, leading to compilation errors.

Understanding Java Access Modifiers

4. Understanding Private Access Modifier in Java

The private access modifier in Java restricts access to entities within the same class, confining its coverage solely to the class where it is declared. This ensures that private members, such as methods and variables, cannot be accessed from outside the class.

4.1 Example - Accessing Private Method from Different Class

In this example, we create a Java file named P.java. Inside this file, there are two classes: A and P, both with default access modifiers. However, class A contains a private method m1. An attempt to create an object of class A and call m1 from class P in the main method results in a compilation error.

// Code: P.java
class A {
  private void m1(){
    System.out.println("A class private method");
  }
}
class P {
  public static void main (String[] args){
    A a = new A();
    a.m1();
  }
}

Upon compilation, an error is encountered, indicating that accessibility is not possible in this case. The diagram illustrates that since method m1 is private, all access activity should be confined within class A only, precluding external access.

Understanding Java Access Modifiers

It is highly recommended to use the private access modifier for variables to prevent access from outside the class, ensuring data hiding. However, for methods that provide functionality akin to a service, public access is recommended for broader accessibility.

5. Understanding Protected Access Modifier in Java

The protected access modifier in Java allows access within the current package and also from outside the package but only through child classes. Before delving into protected access, let's briefly review the concepts of child class and parent class.

A class serves as a template or blueprint for objects, defining their states and behaviors. A child class, or subclass, inherits from a parent class, also known as a superclass or base class.

  1. Class - a group of objects that have states and behavior
  2. Child/Sub Class - is a class that inherits from its parent class
  3. Parent/Super/Base Class - is the class from which its child inherits features

5.1 Example – Child Class and Parent Class

In this example, we create a Java file named X.java. Inside this file, there are three classes: A, B, and X. Class A contains method m1 and is the parent of class B. In class X, we create objects from class A and class B and call m1 using the object created from class B.

// Code X.java
class A {
  public void m1() {
    System.out.println("This is m1 from class A");
  }
}
class B extends A {
  public void m2() {
    System.out.println("This is m1 from class B");
  }
}
class X {
  public static void main(String[] args) {
    A a = new A();
    a.m1();
    B b = new B();
    b.m1();
  }
}

Upon compilation, the code works, and the diagram illustrates how the child class B inherits the method from its parent class A.

Understanding Java Access Modifiers

5.2 Example - Accessing Protected Method within the Same Package

In this example, we create a Java file named C.java. Inside this file, there are two classes: P and C. Class P contains a protected method m1 and is the parent of class C. In class C, we create objects of class P and class C and call m1 of class P and class C.

// Code C.java
package pack1;
class P {
  protected void m1() {
    System.out.println("This is protected method m1 from class P");
  }
}
class C extends P {
  public static void main(String[] args) {
    // First method
    P par = new P();
    par.m1();

    // Second method
    C chi = new C();
    chi.m1();

    // Third method
    P par_chi = new C();
    par_chi.m1();
  }
}

Upon compilation, the code works, and we understand the three possible ways of accessing the protected method within the same package.

5.3 Example - Accessing Protected Method from a Different Package

In this example, we create two Java files named P.java and C.java. Inside P.java, there is a package statement pack1, and class P contains a protected method m1.

// Code P.java
package pack1;
public class P {
  protected void m1() {
    System.out.println("This is protected method m1 from class P");
  }
}

Inside C.java, there is a package statement pack2, and class C extends class P. In class C, we create objects from class P and class C and call m1 using objects created from class P and class C.

// Code C.java
package pack2;
import pack1.P;

class C extends P {
  public static void main(String[] args) {
    // First method
    P par = new P();
    par.m1();

    // Second method
    C chi = new C();
    chi.m1();

    // Third method
    P par_chi = new C();
    par_chi.m1();
  }
}

Upon compilation, an error occurs, highlighting that accessing the protected member from outside the package requires using the child class reference only. The third method demonstrates the correct way to access the protected member from outside the package.

Understanding Java Access Modifiers

6. Summary

In Java programming, access modifiers play a crucial role in defining the visibility or accessibility of classes, methods, variables, and other members within a program. These modifiers ensure the proper encapsulation of code, controlling how different components can be interacted with or accessed by other parts of the program.

6.1 Summary of Access Modifiers

In terms of accessibility or visibility, access modifiers in Java are arranged in a hierarchical order: Public > Protected > Default > Private. This hierarchy determines the extent to which a class, method, or variable can be accessed within the program.

Table of Accessibility for Each Access Modifier

Access Modifier Accessibility/Visibility
Public Accessible from anywhere, within or outside the package.
Protected Accessible within the same package and also from subclasses, even if they are in different packages.
Default Accessible within the same package only. No access is allowed from outside the package.
Private Accessible only within the same class. No access is allowed from outside the class.

Understanding the nuances of each access modifier is essential for creating well-structured and secure Java programs. The following summary provides a quick reference to the accessibility levels associated with each modifier:

Public: Most accessible modifier, allows access from anywhere.

Protected: Accessible within the same package and from subclasses.

Default: Accessible within the same package only.

Private: Most restricted modifier, accessible only within the same class.

6.2 Conclusion

In conclusion, understanding access modifiers is vital for crafting Java code that is both functional and secure. The hierarchical arrangement of access modifiers — from the most accessible, public, to the most restricted, private — empowers developers to control the visibility of their code components, contributing to the overall maintainability and integrity of the software.

By leveraging the appropriate access modifiers, developers can strike a balance between providing necessary access for functionality and restricting access to sensitive components, enhancing the robustness of their Java applications.

End Of Article

End Of Article