What is access specifier
Access specifiers or access modifiers control the visibility of components of a class outside that class.
That is, access specifiers decide that from where a component can be easily accessed.
A component can be a class, constructor, instance variables and methods.

There are 4 types of access modifiers in java.

  1. A component is visible only inside the class in which it is declared. (Private access)
  2. A component is visible only inside the package in which it is declared. (Default access)
  3. A component is visible inside the package in  which it is declared and to sub-classes outside the package. (Protected access)
  4. A component is visible across the application. (Public access)
Access specifiers can be applied to class, constructor, instance variables and methods.

Different access specifiers in java
Java has four access specifiers which decide the visibility of its classes, constructors, fields or methods.
Out of these four access modifiers, three are specified using private, public and protected keywords prefixed before the component whose visibility we need to control.

Fourth one is default access specifier which is automatically applied if none of the above keywords is used to specify access.
All these access specifiers are explained below with example programs.

private access specifier
When this keyword is applied before any component(class, constructor, field, method), then that component is only visible inside the class in which it is declared and not outside the class.
Components outside a class cannot access fields or methods marked private. This is the most restricted access specifier.
Example, below is a class with one private and one public method.
Method marked as public can access the private method since they both are in same class.

package com;

public class PrivateMethodClass {
     
     private void privateMethod() {
          System.out.print("Method not accessible outside this class");
     }

     public void publicMethod() {
        // access private method, no problem
        privateMethod();
     }

}

Now there is another class which creates an object of above class and tries to access its private method as shown below.

package com;

public class PrivateMethodAccess {
     
    public void anotherMethod() {
        PrivateMethodClass obj = new PrivateMethodClass();
        // access public method, no problem
        obj.publicMethod();  
        // access private method, error!!!
        obj.privateMethod();
     }

}

Above code fails with the following error.

com\PrivateMethodAccess.java:8: error: privateMethod() has private access in PrivateMethodClass
obj.privateMethod();
^
1 error

Error clearly says that you are not allowed to access a private method from outside its class.

public access specifier
Anything marked as public is visible everywhere.
By everywhere, it means that it is accessible outside the class, outside the package and even outside the application.

If a component is marked public, then other applications can also access it.
Simple examples are java classes. You can easily access the classes, methods, fields of java api which are marked public.
For example, you can create an object of a java.lang.String, call its subString method etc.
default access specifier
If a class, field, constructor or a method is not preceded with either public, protected or private access specifiers, then it is considered to be default access
It means that absence of any access specifier is default access.
When a component has default access specifier, then it is visible across the package in which it is written.

Thus, if a method has default specifier, then it can be accessed by a class inside the package in which the method is written.
Example, below code has a method which has no access specifier which means it has default access.
The class containing this method is in package com.

package com;
public class DefaultMethodClass {
    void defaultMethod() {
        System.out.print("Method accessible from package com");
    }      
}

There is a class in the same package as the above class shown below.
It creates an object of the above class and calls the method with default access.
There will be no problem at all.

package com;
public class SamePackageClass {
   void callingDefaultMethod() {
      DefaultMethodClass obj = new DefaultMethodClass();
      // no problem, method will be called
      obj.defaultMethod();
   }
}

Now there is a class in another package.
It creates an object of the class with default access method and calls this method.

package com.defaultmethod;

// import class from other package
import com.DefaultMethodClass;

public class DifferentPackageClass {
   void callingDefaultMethod() {
      DefaultMethodClass obj = new DefaultMethodClass();
      // compiler error since method is not visible in this class
      obj.defaultMethod();
   }
}

And the result is

com\defaultmethod\DifferentPackageClass.java:10: error: defaultMethod() is not public in DefaultMethodClass; cannot be accessed from outside packageobj.defaultMethod();
^
1 error

Above error clearly explains that the method with default access is not visible outside the package.

protected access specifier
This access specifier is an extension of default access.

A constructor, field or method with protected access is accessible to all other classes in the same package and to all those classes outside the package which are child classes of the class in which the component with protected access is declared.

Thus,

protected access = Same package + Child classes in different package

Example, below class contains a method with protected access and belongs to package com.

package com;

public class ProtectedMemberClass {
   protected void protectedMethod() {
      System.out.println("Protected Method");
   }
}

Now there is another class in package other which extends the above class.
It contains a method which calls the protected method and there is no problem at all.

package other;

import com.ProtectedMemberClass

public class ProtectedChildClass extends ProtectedMemberClass {
   void callingProtectedMethod() {
     // create object of this class
      ProtectedChildClass obj = new ProtectedChildClass();
      // no problem, method will be called
      obj.protectedMethod();
   }
}

Wait !!! There is more on protected access specifier.

Members of a class marked protected can only be accessed in a sub-class through inheritance. What does that mean?

When a class extends another class, then all the non-private methods and fields of parent class are inherited into the child and behave just like the members of child class.

Thus, when a class extends another class, then all the protected members of parent class become the members of child class and can only be accessed through an object of child class and not through the object of parent class.

Thus, in the above example, if you try to access the protected method in child class as

ProtectedMemberClass obj = new ProtectedMemberClass();
// compiler error !!!
obj.protectedMethod();

You can’t.

Wait…There is even more !!!

Suppose a class Child in a different package p1 extends a class Parent in package p2 and accesses the protected members of another class.
Now there is some other class ChildUser in package p1(same package as Child), which imports Child and creates its object.
Will it be able to access the protected members of Parent?

The answer is NO.
If a class extends another class, then the protected members of parent class become the private members of child class and are only accessible to the child class.

protected access specifier is an extension to default access specifier.

Following table summarizes the scope of components according to their access specifiers and will help to remember them.

Access Specifier Same Class Class in same package Subclass in same package Subclass outside the package Non-subclass outside the package
Public Yes Yes Yes Yes Yes
Protected Yes Yes Yes Yes(through inheritance) No
Default Yes Yes Yes No No
Private Yes No No No No

Let’s tweak in:

  1. Components marked private are not even accessible to the child classes.
  2. protected access specifier can not be applied to a class.
  3. A constructor can also be marked private.
  4. A public class can be accessed from other applications as well.
  5. Java 8 has introduced default methods in interfaces where methods in interfaces are preceded with a default keyword, which is not an access specifier.

Leave a Reply