Java Access Specifiers (also known as Visibility Specifiers) regulate access to classes, fields and methods in Java. They can also be called Access Modifiers. They are usually keywords that determine the accessibility of class, fields and methods in a program. Here the class has control over what data or information is accessed by other classes.
These Specifiers determine whether a field or method in a class can be used or invoked by another method in another class or sub-class. Access Specifiers can also be used to restrict access. Access Specifiers are an integral part of object-oriented programming. In basic terms, they curb access.
There are four Access Specifiers in Java:
package com.javabykiram.encapsulation.accessSpecifier;
class A1 {
private int var = 90;
void testVar() {
A1 a = new A1 ();
System.out.println(a.var); //No Error
}
}
class B {
void testVar() {
A1 a = new A1 ();
//System.out.println(a.var);
//the field a.var is not visible as it is private
}
}
If we make constructor private, we cannot create an object of that class from other classes
Question that may be asked - How you will stop others from creating object of your class? The answer would be: By making constructor private.[this will be more clear in constructor chapter]
In the below given example we may have confusion that
Local variable is not equivalent to instance variable
Local variables cannot be static
private A a1=new A();
Example
package com.javabykiran.Encapsulation.accessSpecifier;
class A {
int jbk = 90;
}
class VarEx {
public A a = new A();
private A a1 = new A();
}
class TestVarEx {
public static void main(String[] args) {
VarEx varex = new VarEx();
System.out.println(varex.a.jbk);
//System.out.println(varex.a1.jbk);
// wrong, a1 is private
}
}
Question: Why should you know private variable? Where have you used in your project?
Answer: :Let’s say we have the following requirement:In a college we want to insert student details and one student insertion means that is:
Now we will start writing a simple class where the above specified requirements will be fulfilled
First approach:
package com.javabykiran.Encapsulation.accessSpecifier;
public class Student {
public void insertStudent() {
// some code for Qual
// logic for Qual insertion
// some code for Personal Detail
// logic for Personal Detail insertion
// some code for Skills
// logic for Skills insertion
// some code for Fees
// logic for Fees insertion
}
}
This approach will not be accepted as all code written is at one place. If, in the future, we want to make fees optional, it won’t be possible and we will need to change whole code which increases unit testing. The above written code will work properly at the first instance, but if we think for the future, then it will be difficult to manage it.
So, we need to change this code as shown below again:
Second approach:
package com.javabykiran.Encapsulation.aceessspecifier;
public class Student {
public void insertStudent() {
insertQual();
insertPD();
insertSkill();
insertFees();
}
public void insertQual()
{
//------
System.out.println("Qualification");
//------
}
public void insertPD()
{
//------
System.out.println("Personal Details");
//------
}
public void insertSkill()
{
//------
System.out.println("Skill Details");
//------
}
public void insertFees()
{
//------
System.out.println("Fees Details");
//------
}
}
In this approach, we just tried to bring more readability and modularity in our code. That means we will have less maintenance. This is just code writing in a different way. It is just copy and pasting code at different places. Now, consider that after some years we want to remove skill insertion. We will then need to comment only one line.
public void insertStudent() {
insertQual();
insertPD();
// insertSkill();
insertFees();
}
Still, our code gets rejected as requirement is not completely fulfilled. HOW??
The client can call any methods directly from outside and can insert anything like fees, etc. But requirement says that all methods should get called so that student will get inserted with all details not just a single or partial detail.
Third approach:
package com.javabykiran.Encapsulation.aceessspecifier;
public class Student {
public void insertStudent()
{
insertQual();
insertPD();
insertSkill();
insertFees();
}
//all below methods are private
private void insertQual()
{
//------
System.out.println("Qualification");
//------
}
private void insertPD()
{
//------
System.out.println("Personal Details");
//------
}
private void insertSkill()
{
//------
System.out.println("Skill Details");
//------
}
private void insertFees()
{
//------
System.out.println("Fees Details");
//------
}
}
This is the most correct approach as all other methods are private and only one method is public which can be accessed from outside.
So, nobody can call any method directly without going through insertStudent method. That's what the requirement says.
Here, it must be noticed how access specifiers play an important role.
If we use them properly, our code will be more managed in the long run.
If any method is overridden from super class to sub class, then the access specifier of the overridden method must be protected or public.
To know this completely, we must know inheritance in detail,please go through inheritance chapter
Private | No Modifier | Protected | Public | |
---|---|---|---|---|
Same class | Yes | Yes | Yes | Yes |
Same package sub-class | No | Yes | Yes | Yes |
Same package non-subclass | No | Yes | Yes | Yes |
Different package subclasses | No | No | Yes | Yes |
Different package non-subclass | No | No | No | Yes |