You are currently viewing Access Modifiers
java_logo

Access Modifiers

Access modifiers in Java are keywords used to control the accessibility of classes, methods, and variables. They determine which other classes can access a particular class, method, or variable.

  1. Private: Access limited to the same class.
  2. Default (Package-Private): Access limited to the same package.
  3. Protected: Accessible within the same package and by subclasses.
  4. Public: Unrestricted access, accessible from any other class.

1. Private Access

In Java, the private access modifier restricts access to members (fields, methods, nested classes) to only the same class where they are declared. Here’s a breakdown:

  • Access Restricted to Same Class: Members marked as private can only be accessed within the same class.
  • Not Accessible Outside the Class: Other classes, even those in the same package or subclasses, cannot access private members.
  • Encapsulation: Encourages encapsulation by hiding implementation details and ensuring that access is controlled through well-defined interfaces.

Here’s a simple example to illustrate private access:

package packageA;

public class MyClass {
    private int privateField;

    private void myPrivateMethod() {
        // Accessing its own private field
        privateField = 20;
    }
}

The privateField is a private member of the MyClass class. It cannot be accessed directly from outside the MyClass class. However, within the MyClass class, such as in the myPrivateMethod() method, the privateField can be accessed and modified without any restrictions.

This encapsulation ensures that the internal state of the MyClass class is hidden from external classes, enhancing data integrity and preventing unintended access or modification of sensitive data.

Now, let’s visualize this with a figure:

-----------------    -----------------
|   Package A   |    |   Package B   |
-----------------    -----------------
|   MyClassA    |    |   MyClassB    |
|   [private]   |    |   [private]   |   
|               |    ----------------- 
|               | 
|  AnotherClass |   
|   [private]   |               
-----------------    

In the figure above:

  • MyClass is located in Package A.
  • It has a private member (field or method).
  • Classes in Package B cannot access the private member of MyClass.
  • Other classes in Package A cannot access the private member of MyClass.
package packageB;

import packageA.MyClass;

public class AnotherClass {
    public void doSomethingElse() {
        MyClass obj = new MyClass();
        obj.myPrivateMethod(); // Compilation error
    }
}
package packageA;

public class AnotherClass {
    public AnotherClass() {
        MyClass myClass = new MyClass();

         System.out.println(myClass.privateField); // Compilation Error
         myClass.privateMethod(); // Compilation Error

    }
}

2. Default (Package-Private) Access

Default access (also known as package-private) allows members (fields, methods, and constructors) to be accessible within the same package but not from outside the package. It’s the access level used when no access modifier is specified.

Let’s have a look at the figure for this section:

----------------------------------------------
|                package packageA           |
|--------------------------------------------|
|                                            |
|    MyClass                                 |
|    ------------------------------------    |
|    | privateField: int                |    |
|    | defaultField: int (default)      |    |
|    ------------------------------------    |
|    | myPublicMethod()                |    |
|    | myPrivateMethod()               |    |
|    ------------------------------------    |
|                                            |
|                                            |
|                                            |
|    AnotherClass                            |
|    ------------------------------------    |
|    | myMethod()                       |    |
|    ------------------------------------    |
|                                            |
----------------------------------------------




----------------------------------------------
|                package packageB           |
|--------------------------------------------|
|                                            |
|    MyClassB                                |
|    ------------------------------------    |
|    | myMethodB()                      |    |
|    ------------------------------------    |
|                                            |
----------------------------------------------

Here is a code example to illustrate this:

// MyClass.java
package packageA;

public class MyClass {
    private int privateField;
    int defaultField;

    public void myPublicMethod() {
        System.out.println("Public Method");
    }

    private void myPrivateMethod() {
        System.out.println("Private Method");
    }
}

// AnotherClass.java
package packageA;

public class AnotherClass {
    public void myMethod() {
        MyClass myClass = new MyClass();

        // Compilation error: privateField has private access in MyClass
        System.out.println(myClass.privateField);

        // Compilation error: myPrivateMethod() has private access in MyClass
        myClass.myPrivateMethod();

        // Accessing defaultField
        System.out.println(myClass.defaultField);
    }
}

// MyClassB.java
package packageB;

import packageA.MyClass;

public class MyClassB {
    public void myMethodB() {
        MyClass myClass = new MyClass();

        // Compilation error: privateField has private access in MyClass
        System.out.println(myClass.privateField);

        // Compilation error: defaultField has default access in MyClass
        System.out.println(myClass.defaultField);
    }
}

In this setup:

  • MyClass has private and default fields (privateField and defaultField, respectively).
  • AnotherClass, in the same package as MyClass, tries to access both private and default fields of MyClass. It can access the defaultField but not the privateField.
  • MyClassB, in a different package from MyClass, tries to access both private and default fields of MyClass. It cannot access either the privateField or the defaultField.

3. Protected Access

Protected access is more permissive than private and default access, but more restrictive than public access. It allows access within the same package and from subclasses, even if they are located in different packages.

Here is the figure for this section:

----------------------------------------------
|                package packageA           |
|--------------------------------------------|
|                                            |
|    MyClass                                 |
|    ------------------------------------    |
|    | privateField: int                |    |
|    | defaultField: int (default)      |    |
|    ------------------------------------    |
|    | myPublicMethod()                |    |
|    | myPrivateMethod()               |    |
|    ------------------------------------    |
|                                            |
|    AnotherClass                            |
|    ------------------------------------    |
|    | myMethod()                       |    |
|    ------------------------------------    |
|                                            |
|    SubclassA extends MyClass               |
|    ------------------------------------    |
|    | myMethod()                       |    |
|    ------------------------------------    |
|                                            |
----------------------------------------------


----------------------------------------------
|                package packageB           |
|--------------------------------------------|
|                                            |
|    MyClassB                                |
|    ------------------------------------    |
|    | myMethodB()                      |    |
|    ------------------------------------    |
|                                            |
|    SubclassB extends MyClass               |
|    ------------------------------------    |
|    | myMethodB()                      |    |
|    ------------------------------------    |
|                                            |
|    OtherClass                              |
|    ------------------------------------    |
|    | otherMethod()                    |    |
|    ------------------------------------    |
|                                            |
----------------------------------------------
  • SubclassA and SubclassB are subclasses of MyClass in their respective packages.
  • SubclassA and SubclassB can access the protected and public members of MyClass.
  • OtherClass is a non-subclass class in each package.
  • OtherClass cannot access the protected members of MyClass unless it is in the same package as MyClass.

here’s an example illustrating the accessibility of protected members:

package packageA;

public class MyClass {
    private int privateField;
    int defaultField;
    protected int protectedField;

    public MyClass() {
        this.privateField = 10;
        this.defaultField = 20;
        this.protectedField = 30;
    }

    public void accessFields() {
        // Accessible within MyClass
        System.out.println("Private field: " + privateField); 
        // Accessible within MyClass and packageA
        System.out.println("Default field: " + defaultField); 
        // Accessible within MyClass, packageA, and subclasses 
        System.out.println("Protected field: " + protectedField);  
    }
}
package packageA;

public class AnotherClass {
    public void accessFields() {
        MyClass myClass = new MyClass();

        // Accessing protected field from MyClass
        System.out.println(myClass.protectedField); 
    }
}
package packageB;

import packageA.MyClass;

public class OtherClass {
    public void accessFields() {
        MyClass myClass = new MyClass();

        // Accessing fields from MyClass
         System.out.println(myClass.privateField);  // compilation error
         System.out.println(myClass.defaultField);  // compilation error
         System.out.println(myClass.protectedField); // compilation error
    }
}
package packageB;

import packageA.MyClass;

public class SubclassB extends MyClass {
    public void accessFields() {
        MyClass myClass = new MyClass();

        // Accessing fields from MyClass
         System.out.println(myClass.privateField);  // compilation error
         System.out.println(myClass.defaultField);  // compilation error
       // Accessible from subclasses
         System.out.println(myClass.protectedField); 
    }
}
  • privateField is accessible only within the MyClass itself.
  • defaultField is accessible within MyClass and any other class in the same package (packageA).
  • protectedField is accessible within MyClass, any other class in the same package (packageA), and its subclasses (SubclassB in packageB).

The OtherClass in packageB cannot access privateField or defaultField from MyClass because it is in a different package. Similarly, the SubclassB can access protectedField because it is a subclass, but it cannot access privateField or defaultField directly from MyClass because they are not visible outside of MyClass or packageA. AnotherClass in packageA can access the protected fields of MyClass since it’s in the same package.

4. Public Access

Public access modifier allows members to be accessible from anywhere, both within and outside the package. Public members can be accessed by any other class or package.

Here’s a code example to illustrate public access:

package packageA;

public class MyClass {
    public int publicField;

    public MyClass() {
        this.publicField = 100;
    }

    public void publicMethod() {
        System.out.println("This is a public method.");
    }
}
package packageB;

import packageA.MyClass;

public class AnotherClass {
    public void accessPublicMembers() {
        MyClass myClass = new MyClass();

        // Accessing public field and method from MyClass
        System.out.println("Public field value: " + myClass.publicField); 
        myClass.publicMethod();
    }
}

In this example, AnotherClass in packageB can access the public field and method of MyClass from packageA. This demonstrates the public access modifier’s ability to allow members to be accessed from outside the package.