Modifiers are specific keywords present in Java using that we can make changes to the characteristics of a variable, method, or class and limit its scope. Java programming language has a rich set of Modifiers.
There are two types of modifiers in Java: access modifiers and non-access modifiers.
The access modifiers in Java specifies the accessibility or scope of a field, method, constructor, or class. We can change the access level of fields, constructors, methods, and class by applying the access modifier on it.
There are 4 types of Java access modifiers:
Access Modifier
Descriptions
private
The access level of a private modifier is only within the class. It cannot be accessed from outside the class.
default
The access level of a default modifier is only within the package. It cannot be accessed from outside the package. If you do not specify any access level, it will be the default.
protected
The access level of a protected modifier is within the package and outside the package through child class. If you do not make the child class, it cannot be accessed from outside the package.
public
The access level of a public modifier is everywhere. It can be accessed from within the class, outside the class, within the package and outside the package.
Access Modifier
Within Class
Within Package
Outside Package By Subclass Only
Outside Package
private
Y
N
N
N
default
Y
Y
N
N
protected
Y
Y
Y
N
public
Y
Y
Y
Y
Let's see the example below for more details.
For example, we have a class AccessExample in the package com.java.core.accessmodifier.samepackage as below.
AccessExample.java
1 2 3 4 5 6 7 8 91011121314151617181920
packagecom.java.core.accessmodifier.samepackage;publicclassAccessExample{privateStringprivateVariable;// private access modifierStringdefaultVariable;// default access modifierprotectedStringprotectedVariable;// protected access modifierpublicStringpublicVariable;// public access modifierpublicvoidaccessExample(){// Access within the classprivateVariable="Private variable accessed within the class";defaultVariable="Default variable accessed within the class";protectedVariable="Protected variable accessed within the class";publicVariable="Public variable accessed within the class";}}
This class contains 4 fields with 4 access modifiers. So by default, all fields with all these access modifiers can be accessed inside it.
Now, let's create another class which is in the same package with the class above. As you can see, for the private field, we can't access it.
SamePackage.java
1 2 3 4 5 6 7 8 910111213
packagecom.java.core.accessmodifier.samepackage;publicclassSamePackage{publicvoidaccessExample(){// Access within the packageAccessExampleobj=newAccessExample();obj.defaultVariable="Default variable accessed within the package";obj.protectedVariable="Protected variable accessed within the package";obj.publicVariable="Public variable accessed within the package";}}
Next, let's create another package with another class which will extends the AccessExample class as below.
SubclassExample.java
1 2 3 4 5 6 7 8 91011
packagecom.java.core.accessmodifier.anotherpackage;importcom.java.core.accessmodifier.samepackage.AccessExample;publicclassSubclassExampleextendsAccessExample{publicvoidaccessExample(){// Access outside the package by subclass onlyprotectedVariable="Protected variable accessed outside the package by subclass only";publicVariable="Public variable accessed outside the package by subclass only";}}
As you can see, we can only access the protectedVariable and publicVariable.
Finally, let's create another class in the another package which doesn't extend the AccessExample class, then we can see that we only can access the publicVariable.
OutsidePackageExample.java
1 2 3 4 5 6 7 8 91011
packagecom.java.core.accessmodifier.anotherpackage;importcom.java.core.accessmodifier.samepackage.AccessExample;publicclassOutsidePackageExample{publicvoidaccessExample(){// Access outside the packageAccessExampleobj=newAccessExample();obj.publicVariable="Public variable accessed outside the package";}}
The non-access modifiers provide information about the characteristics of a class, method, or variable to the JVM. There are seven types of Non-Access modifiers in Java.
Modifier Name
Overview
static
The member belongs to the class, not to objects of that class.
final
Variable values can't be changed once assigned, methods can't be
abstract
If applied to a method - has to be implemented in a subclass, if
synchronized
Controls thread access to a block/method.
volatile
The variable value is always read from the main memory, not from
The final keyword in java is used to restrict the user. The java final keyword can be used in many context. Final can be
variable
method
class
The final keyword can be applied with the variables, a final variable that have no value, it is called blank final variable or uninitialized final variable. It can be initialized in the constructor only. The blank final variable can be static also which will be initialized in the static block only.
If you make any variable as final, you can not change the value of final variable (It will be constant)
If you make any method as final, you can not override it.
If you make any class as final, you can not inherit it.
Example with final for variable
FinalVariableExample.java
1 2 3 4 5 6 7 8 910111213141516
packagecom.java.core.nonmodifier;publicclassFinalVariableExample{publicstaticfinalStringCONSTANT_VARIABLE="This is a constant";privatefinalStringfinalParameter;publicFinalVariableExample(StringfinalParameter){this.finalParameter=finalParameter;}publicStringgetFinalParameter(){returnfinalParameter;}}
packagecom.java.core.nonmodifier;publicclassExtendFinalMethodExampleextendsFinalMethodExample{// can not override final method of FinalMethodExample. Compile Error// @Override// public final void printSomething(String something) {// System.out.println("printSomething: " + something);// }@OverridepublicvoidprintData(Stringdata){System.out.println("Override printDate: "+data);}}
packagecom.java.core.nonmodifier;//Can not extend Compile ErrorpublicclassExtendFinalClassExampleextendsFinalClassExample{}
JavaFinalMain.java
1 2 3 4 5 6 7 8 9101112
packagecom.java.core.nonmodifier;publicclassJavaFinalMain{publicstaticvoidmain(String[]args){FinalClassExamplefinalClassExample=newFinalClassExample();finalClassExample.setExampleParam("final class with example param");System.out.println(finalClassExample.getExampleParam());finalClassExample.printSomething("something");}}
Result
12
final class with example param
FinalClass printSomething: something
The static keyword in Java is used for memory management mainly. We can apply static keyword with variables, methods, blocks and nested classes. The static keyword belongs to the class than an instance of the class.
The static variable can be used to refer to the common property of all objects (which is not unique for each object). The static variable gets memory only once in the class area at the time of class loading.
Variables declared static can be accessed via the class name (instead of the usual object reference, e.g. (MyClass.staticVariable), and they can be accessed without the class being instantiated.
static variable makes our program memory efficient (i.e., it saves memory).
So for example, Let's create a class with a static field as below.
StaticVariable.java
1 2 3 4 5 6 7 8 91011
packagecom.java.core.nonmodifier;publicclassStaticVariableClassExample{staticintcount;// static variablepublicStaticVariableClassExample(){count++;// accessing and modifying static variable}}
In this class, we just simply have a static field and a constructor which will modify the value of this static field.
Now, let's create a main class and use the static variable of the class above.
JavaStaticMain.java
1 2 3 4 5 6 7 8 910
packagecom.java.core.nonmodifier;publicclassJavaStaticMain{publicstaticvoidmain(String[]args){System.out.println("countValue is "+StaticVariableClassExample.count);StaticVariableClassExamplestaticVariable=newStaticVariableClassExample();System.out.println("countValue is "+StaticVariableClassExample.count);}}
1234
countValue is 0
countValue is 1
Process finished with exit code 0
As you can see, we can access the static field via class name and without the instantiated of StaticVariable class
If we apply static keyword with any method, it is known as static method.
A static method belongs to the class rather than the object of a class.
A static method can be invoked without the need for creating an instance of a class.
A static method can access static data member and can change the value of it.
The static methods can only use static variables and call other static methods, and cannot refer to this or super in any way (an object instance might not even exist when we call a static method, so this wouldn't make sense).
Note: It's very important to note that static variables and methods can't access non-static (instance) variables and methods. On the other hand, non-static variables and methods can access static variables and methods.
This is logical, as static members exist even without an object of that class, whereas instance members exist only after a class has been instantiated.
So for example, Let's create a class with a static method as below.
Then inside this class, we can't access the class variable from the static method and like the static variable we can access the static method without the instantiated class.
StaticMethodClassExample.java
1 2 3 4 5 6 7 8 910
packagecom.java.core.nonmodifier;publicclassJavaStaticMain{publicstaticvoidmain(String[]args){System.out.println("Sum of a and b: "+StaticMethodClassExample.add(5,5));}}
1234
Example Static Value
Sum of a and b: 10
Process finished with exit code 0
Static block: A static block is a block of code that is associated with a static keyword and is executed only once when the class is loaded into memory. It can be used for static initialization of a class.
Calling static block: A static block is automatically called as soon as the class is loaded in memory. There is no need to explicitly call it. It can also be executed before the main method at the time of classloading.
Static block and JDK version: A static block can print if the JDK version is 1.6 or previous. If the JDK version is later, it will throw an error.
Number and order of static blocks: A class can have any number of static blocks and they can appear anywhere in the class body. They are called in the order that they appear in the source code
So let's take an example, we will create a class with name StaticBlockClassExample as below.
StaticBlockClassExample.java
1 2 3 4 5 6 7 8 9101112
packagecom.java.core.nonmodifier;publicclassStaticBlockClassExample{staticintcount;static{count=10;// initializing static variable in static blockSystem.out.println("count Value is: "+count);}}
As you can see in the static block we can instantiate the value for static variables.
Next, if we define static blocks inside the main class then they will be executed before the main method is executed and the order of static blocks will base on where they are defined in the source code.
JavaStaticMain.java
1 2 3 4 5 6 7 8 9101112131415161718
packagecom.java.core.nonmodifier;publicclassJavaStaticMain{static{System.out.println("This static block runs before the main method of JavaStaticMain 1");}publicstaticvoidmain(String[]args){System.out.println("StaticBlockClassExample count Value is: "+StaticBlockClassExample.count);}static{System.out.println("This static block runs before the main method of JavaStaticMain 2");}}
Now, let's execute the main class then you can see the log as below.
123456
This static block runs before the main method of JavaStaticMain 1
This static block runs before the main method of JavaStaticMain 2
count Value is: 10
StaticBlockClassExample count Value is: 10
Process finished with exit code 0