Access Specifiers in Java | Access Modifiers
Contents
Overview
In this article, we will learn about different types of access specifiers available in Java. In other words, we will discuss the scope of visibility of variables and methods within a program.
Types of Access Specifiers in Java
- The job of access specifier is to specify the scope of a variable (data member), function (method), constructor or any class.
- We can also call these prefixes as access modifiers.
Large programs contain a large number of classes and methods. Many of the methods are reused in the program. In such a scenario, having control over the accessibility of the members becomes necessary. Programmers use these words to achieve control over the visibility of classes, functions and data members.
Java supports 4 access specifiers:
The table below sums up the visibility ranges of all the access specifiers.
Public Access Specifier
- This provides the widest range of visibility within a program.
- Anyone can access the methods and classes which are declared as public irrespective of their locations in the program.
- Java does not support any global member unlike C++, C. If we declare a member as public, it behaves like a global member in Java.
package test; public class TestPublic { public static int x = 10; public int y ; } package test; public class WithinPublic { public static void main(String[] args) { // public variables x and y can be accessed within the package // value of static variable x is displayed System.out.println("value of x from TestPublic clas = " + TestPublic.x); TestPublic obj = new TestPublic(); obj.y = 40; // value of static variable y is displayed System.out.println("value of y from TestPublic clas = " + obj.y); } } package test_2; import test.TestPublic; public class OutsidePkgPubic { public static void main(String[] args) { // public variables x and y can be accessed outside the package // value of static variable x is displayed System.out.println("value of x from TestPublic clas = " + TestPublic.x); TestPublic obj = new TestPublic(); obj.y=20; //value of static variable y is displayed System.out.println("value of y from TestPublic clas = " + obj.y); } }
The output of the program:
This output image shows “public variables can be accessed within the same package“.
This output image shows “methods and classes present in another outside package can access public variables“.
Protected Access Specifier
- When we declare a member with the “protected” keyword, it becomes a protected member which in turn reduces its visibility to the world.
- For example,
protected int y ;
protected static int x = 10;
- This form of access modifier gives access to members of the same package to access the protected variables and methods.
- If functions are present inside the same class or in another class but within the same package, they can access the protected members.
- Outside the package, only the subclasses can view the protected members of its parent class.
- Generally, we use this access specifier when we want to hide the members of a class from the world but only give access to its subclass.
- This keyword hides and protects the data of a class from other non-related classes.
package test; public class TestProtected { protected static int x = 10; protected int y ; } package test; public class WithinProtected { public static void main(String[] args) { // variables x and y can be accessed within the package System.out.println("value of x from TestProtected clas = " + TestProtected.x); TestProtected obj = new TestProtected(); obj.y= 40; //Non static variable's value is displayed System.out.println("value of x from TestProtected clas = " + obj.y); } } package test_2; import test.TestProtected; public class OutsidePkgProtected { public static void main(String[] args) { // protected variables x and y cannot be accessed outside the package // as they are not visible outside the package // static variable's value is not displayed System.out.println("value of x from TestProtected clas = " + TestProtected.x); TestProtected obj = new TestProtected(); obj.y=20; // Non static variable's value is not displayed System.out.println("value of x from TestProtected clas = " + obj.y); } }
Outputs of the above program:
“protected variables can be accessed by all the methods and classes within the same package“. In the below image, you can see the correct values are displayed.
In the image below, you get to know that “methods and classes present in another outside package cannot access protected variables”. It will provide compilation errors if you try to access a protected member outside its package.
However, subclasses can access the protected variables of its parent class. It does not matter if they share the same or are parts of two different packages.
(You will learn this concept of the subclass and parent class under the article “Inheritance in Java”.
Default Access Specifier
- If while declaring a member, we do not specify any access modifier explicitly, then it becomes a default member. For example,
String name;
int number = 10;
- Default members are visible within the same package. Members of the same class as well as members of a different class within the same package can access the default members.
- Even the subclasses cannot view or access the default members of its parent class.
Thus this access specifier is more restrictive than protected.
package test; public class TestDefault { // these variables have default access specifier as no specifier is mentioned static int x = 10; int y ; public static void main(String[] args) { // default variables can be accessed within same class // static variable's value is displayed System.out.println("value of x from TestDefault clas = " + TestDefault.x); TestDefault obj=new TestDefault(); obj.y = 25; // Non static variable's value is displayed System.out.println("value of x from TestDefault clas = " + obj.y); } } package test; public class WithinDefault { public static void main(String[] args) { // variables x and y can be accessed within the package // static variable's value is displayed System.out.println("value of x from TestDefault clas = " + TestDefault.x); TestDefault obj = new TestDefault(); obj.y = 45; // Non static variable's value is displayed System.out.println("value of x from TestDefault clas = " + obj.y); } } package test_2; import test.TestDefault; public class OutsidePkgDefault { public static void main(String[] args) { // default variables x and y cannot be accessed outside the package // as they are not visible outside the package // static variable's value is not displayed System.out.println("value of x from TestDefault clas = " + TestDefault.x); TestDefault obj = new TestDefault(); obj.y=20; // Non static variable's value is not displayed System.out.println("value of x from TestDefault clas = " + obj.y); } }
The output of the program:
“all the members within the same class can access the default members“.
This output image shows “all the members of different classes within the same package can access the default members”.
This output image shows “methods and classes present in another outside package cannot access default members”. Even subclasses cannot access the default members of the parent class. If you try accessing default members outside of the package, it gives an error as follows:
Private Access Specifiers
- This provides the narrowest form of visibility out of all the access specifiers.
- Only the class containing the private variable declaration can access it.
- No other classes or members present outside of that declared class is aware of the private data member.
- With the help of this private keyword, a class hides and encapsulates its data from the outside world.
- You should not declare Classes and Interfaces as private as they have to be reused by other classes.
For example:
private static int x = 10;
private int y ;
Refer to the below program to understand the visibility of a private data member.
package test; public class TestPrivate { // these variables have private access specifier and will only be visible within same class. private static int x = 10; private int y ; public static void main(String[] args) { // default variables can be accessed within same class // static variable's value is displayed System.out.println("value of x from TestPrivate clas = " + TestPrivate.x); TestPrivate obj=new TestPrivate(); obj.y=35; // Non static variable's value is displayed System.out.println("value of x from TestPrivate clas = " + obj.y); } } package test; public class WithinPrivate { public static void main(String[] args) { // variables x and y can be accessed within the package // static variable's value is not displayed System.out.println("value of x from TestPrivate clas = " + TestPrivate.x); TestPrivate obj = new TestPrivate(); obj.y= 45; // Non static variable's value is not displayed System.out.println("value of x from TestPrivate clas = " + obj.y); } } package test_2; import test.TestPrivate; public class OutsidePkgPrivate { public static void main(String[] args) { // variables x and y can be accessed within the package // static variable's value is not displayed System.out.println("value of x from TestPrivate clas = " + TestPrivate.x); TestPrivate obj = new TestPrivate(); obj.y= 45; // Non static variable's value is not displayed System.out.println("value of x from TestPrivate clas = " + obj.y); } }
The output of the program:
“All the members within the same class can access the private members“.
“Private members cannot be accessed outside the package or outside the class.”
The above two images show that you will get a compilation error if you try to access private members anywhere outside of its class. Thus this access specifier gives the strongest form of visibility restriction over members of a class.
However, other classes can use private members if that declared class contains public getter and public setter methods.
Go through the below program to understand how getter and setter methods help to use a private data member.
package test; public class TestPrivate { // these variables have private access specifier private static int x=1; private static int a; // public getter method to get the variable value outside of the class public int xgetter() { return TestPrivate.x; } // public setter method to get the variable value outside of the class public int asetter(int b) { return TestPrivate.a = b; } } package test; public class WithinPrivate { public static void main(String[] args) { // variables x and y can be accessed within the package TestPrivate obj = new TestPrivate(); obj.xgetter(); // Non static variable's value is displayed System.out.println("value of x from TestPrivate clas = " + obj.xgetter()); int result=obj.asetter(4); // Non static variable's value is displayed System.out.println("value of a from TestPrivate clas = " + result); } } package test_2; import test.TestPrivate; public class OutsidePkgPrivate { public static void main(String[] args) { // outside the package TestPrivate obj = new TestPrivate(); obj.xgetter(); System.out.println("value of x from TestPrivate clas = " + obj.xgetter()); int result=obj.asetter(12); // Non static variable's value is displayed System.out.println("value of a from TestPrivate clas = " + result); } }
In the below output pictures you can see values of a is modified outside of its class.
So, this was all about the available access specifiers in Java. You must use these keywords wisely to gain control over the data members of a class. This will help you to protect the classes and encourage data encapsulation and data hiding.
Don’t worry, you can learn about these terminologies article “Concept of OOPs in Java- Basic Terminology”!
In the next article, I will discuss the Data Types and Wrapper classes present in Java.