Understanding and using Access Specifiers in Java


Reading time: 30 minutes

Access specifiers are utilities/ code features that restrict the access to a particular code feature or data depending upon the source of the code requesting the access. This provides a simple way to make code more secure and keep everything in control.

Accessing a member of a class depends lot on the access specifier or access labels. Access specifiers control access to members of a class from within a java program. The access levels or access specifiers supported by java are: private, public, protected and default.

In this article, we will learn about:

  • the different types of access specifiers
  • why we need access specifiers and when to use them in Java?

Why we need access specifiers?

We need access specifiers to control who is accessing our data or features. This allows us to:

  • prevent users to access data when want them not to access
  • allow certain users to use only particular features. This is widely used as paid users of software services are given access to extra features.

The challenge arises as we have multiple users of a particular service or software like public users, paid users, testers, developers, adminstrators and others. We need to specify different access rules for different users and this can be done by checking the user type

Similarly, when it comes to code, we need to provide different access rules for codes coming from different source. To manage this, Java provides 4 simple yet effective access specifier which we will explore now.

Different access specifiers in Java?

  • private- This access specifier denotes a variable or a method as being private to the class and may not be accessed outside the class.Accessing will be done through calling one of the public class methods.

  • protected- This access specifier denotes a variable or method as being public to the subclasses and being private to all other classes outside the current package. So, child classes have the ability to access protected variables of its parents.

Note:In OOP languages, classes can inherit properties from another class.This is called inheritance.The inheriting class is subclass or derived class and the class being inherited is super class or base class. eg: humans are the subclass of mammals.

  • public- This access specifier denotes a variable or method as being directly accessible from all other classes.

  • default- If no other access specifier is used, then the class member has default access.It is also known as friendly access.

Access specifier: private

This is the most restrictive access level. This access specifier should be used to declare members that should only be used by the class.To declare private member you must use the private keyword.Consider the following code:

class Alpha
{
    private int iamprivate;            //private data member
    private void privateMethod()       //private method
    {
        System.out.println("I am a private method");
    }
}

Objects of Alpha can modify the iamprivate variable and invoke the privateMethod().But,objects of other types cannot do so.For example,the Beta class cannot:

class Beta
{
    void accessMethod()
    {
        Alpha a=new Alpha();
        //Trying to access private methods and members
        a.iamprivate=10;          //Illegal- a compilation error
        a.privateMethod();        //Illegal- a compilation error
    }
}

Access Specifier: protected

This allows the class itself, subclasses and all the classes in the same package have to access the members.Let us consider a class Alpha defined inside a Greek package.

package Greek;
class Alpha
{
    protected int iamprotected;
    protected void protectedMethod()
    {
        System.out.println("I am protected");
    }
}

Let us say there is an another class Gamma which is also is a class in the Greek package:

package Greek;
class Gamma
{
    void accessMethod()
    {
        Alpha a =new Alpha();
        a.iamprotected=10;         //legal
        a.protectedMethod();       //legal
    }
}

Let us have another class Delta that is derived from Alpha but lives in a different package-Latin. Delta class cannot access iamprotected and protectedMethod() on objects of type Alpha.

package Latin;
import Greek.*;
class Delta extends Alpha
{
    //It means class Delta is inheriting members of class Alpha.
    void accessMethods(Alpha a,Delta d)
    {
        a.iamprotected=10;         //Illegal as it is in different package
        a.protectedMehod();        //Illegal as it is in different package
        d.iamprotected=10;         //legal as Delta has inherited Alpha
        d.protectedMethod();       //legal as Delta has inherited Alpha
    }
}

Access specifier: public

Any class, in any package has access to a class's public members.For example:

package Greek;
class Alpha
{
    public int iampublic;      //public data member
    public void publicMethod()  //public method
    {
        System.out.println("I am a public method");
    }
}

Let us say Beta is defined in another class

package Roman;
import Greek.*;
class Beta
{
    void accessMethod()
    {
        Alpha a= new Alpha();

        a.iampublic=10;        //legal
        a.publicMethod();      //legal
    }
}

public members are accessible in all classes.

Access specifier: friendly (default)

Java assumes this access specifier if you don't explicitly set any member's access level or access specifier.This assumes that all the classes in the same package are trusted friends.

Let us consider an example:

package Greek;
class Alpha
{
    int iampackage;
    void packageMethod()
    {
        System.out.println("I am a package method");
    }
}

Let us say Beta class in the same package

package Greek;
class Beta
{
    void accessMethod()
    {
        Alpha a=new Alpha();

        a.iampackage=10;         //legal
        a.packageMethod();       //legal
    }
}

Note: the default access specifier is friendly,but is not a keyword.Friendly means all the friends(classes in the same package) can access it.