Modifiers are specific keywords present in Java using which 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.
Modifiers in Java are divided into two types – Access Modifiers and Non-Access modifiers.
Access Modifiers in Java help restrict the scope of a variable, method, class, or constructor. Public, Private, Protected, and Default these four access modifiers are present in Java.
Non-Access modifiers
Non-access modifiers provide information about the characteristics of a class, method, or variable to the JVM. Seven types of Non-Access modifiers are present in Java. They are –
- static
- final
- abstract
- synchronized
- volatile
- transient
- native
The static keyword means that the entity to which it is applied is available outside any particular instance of the class. That means the static methods or the attributes are a part of the class and not an object. The memory is allocated to such an attribute or method at the time of class loading. The use of a static modifier makes the program more efficient by saving memory. A static field exists across all the class instances, and without creating an object of the class, they can be called.
Example 1:
Java
import java.io.*;
class static_gfg {
static String s = "GeeksforGeeks" ;
}
class GFG {
public static void main(String[] args)
{
System.out.println(
static_gfg.s);
}
}
|
In this above code sample, we have declared the String as static, part of the static_gfg class. Generally, to access the string, we first need to create the object of the static_gfg class, but as we have declared it as static, we do not need to create an object of static_gfg class to access the string. We can use className.variableName for accessing it.
Example 2:
Java
import java.io.*;
class static_gfg {
static int count = 0 ;
void myMethod()
{
count++;
System.out.println(count);
}
}
class GFG {
public static void main(String[] args)
{
static_gfg obj1 = new static_gfg();
obj1.myMethod();
static_gfg obj2
= new static_gfg();
obj2.myMethod();
}
}
|
In the above code, the count variable is static, so it is not tied to a specific instance of the class. So, while obj1.myMethod() is called it increases the value of count by 1 and then obj2.myMethod() again increases it . If it was not a static one, then we will get output as 1 in both cases, but as it is a static variable so that count variable will be increased twice, and we will get 2 as an output the second time.
The final keyword indicates that the specific class cannot be extended or a method cannot be overridden. Let’s understand that with an example –
Example 1:
Java
import java.io.*;
class final_gfg {
String s1 = "geek1" ;
}
class extended_gfg extends final_gfg {
String s2 = "geek2" ;
}
class GFG {
public static void main(String[] args)
{
extended_gfg obj = new extended_gfg();
System.out.println(obj.s1);
System.out.println(obj.s2);
}
}
|
In this above code, the final_gfg class is extended by the extended_gfg class, and the code is working fine and producing output.
But after using the final keyword with the final_gfg class. The code will produce an error. Below is the implementation for the same –
Java
import java.io.*;
final class final_gfg {
String s1 = "geek1" ;
}
class extended_gfg extends final_gfg {
String s2 = "geek2" ;
}
class GFG {
public static void main(String[] args)
{
extended_gfg obj
= new extended_gfg();
System.out.println(obj.s1);
System.out.println(obj.s2);
}
}
|
Error :

Screenshot of Error
Here we are getting errors in the compilation as we are trying to extend the final_gfg class, which is declared as final. If a class is declared as final, then we cannot extend it or inherit from that class.
Example 2:
Java
import java.io.*;
class final_gfg{
void myMethod(){
System.out.println( "GeeksforGeeks" );
}
}
class override_final_gfg extends final_gfg{
void myMethod(){
System.out.println( "Overrides GeeksforGeeks" );
}
}
class GFG{
public static void main(String[] args) {
override_final_gfg obj= new override_final_gfg();
obj.myMethod();
}
}
|
OutputOverrides GeeksforGeeks
In the above code, we are overriding myMethod(), and the code is working fine.
Now we are going to declare the myMethod() in superclass as final. Below is the implementation for the same –
Java
import java.io.*;
class final_gfg{
final void myMethod(){
System.out.println( "GeeksforGeeks" );
}
}
class override_final_gfg extends final_gfg{
void myMethod(){
System.out.println( "Overrides GeeksforGeeks" );
}
}
class GFG{
public static void main(String[] args) {
override_final_gfg obj= new override_final_gfg();
obj.myMethod();
}
}
|
Error:

Screenshot of Error
The above code is producing an error because here, we are trying to override a method that is declared as final. myMethod() in the final_gfg class is declared as final, and we are trying to override that from the override_final_gfg class. A final method cannot be overridden; thus, the code snippet is producing an error here.
abstract keyword is used to declare a class as partially implemented means an object cannot be created directly from that class. Any subclass needs to be either implement all the methods of the abstract class, or it should also need to be an abstract class. The abstract keyword cannot be used with static, final, or private keywords because they prevent overriding, and we need to override methods in the case of an abstract class.
Java
abstract class abstract_gfg{
abstract void myMethod();
}
class MyClass extends abstract_gfg{
void myMethod(){
System.out.println( "GeeksforGeeks" );
}
}
class GFG{
public static void main(String[] args) {
MyClass obj= new MyClass();
obj.myMethod();
}
}
|
In the above code, abstract_gfg is an abstract class, and myMethod() is an abstract method. So, we first need to extend the abstract_gfg class that we have done here using MyClass. After extending, we also need to override the abstract method otherwise, the code will produce errors.
synchronized keyword prevents a block of code from executing by multiple threads at once. It is very important for some critical operations. Let us understand by an example –
Java
import java.io.*;
class Counter{
int count;
void increment(){
count++;
}
}
class GFG{
public static void main(String[] args) throws InterruptedException {
Counter c= new Counter();
Thread t1= new Thread( new Runnable() {
@Override
public void run() {
for ( int i= 1 ;i<= 10000 ;i++){
c.increment();
}
}
});
Thread t2= new Thread( new Runnable() {
@Override
public void run() {
for ( int i= 1 ;i<= 10000 ;i++){
c.increment();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(c.count);
}
}
|
Output

The above code should be an output value of 20000 as two threads increment it 10000 times each, and the main is waiting for Thread1, and Thread2 to finish. Sometimes it may not be true. Depending upon the system, it may not give 20000 as output. As both threads are accessing the value of count, it may happen that Thread1 fetches the value of count, and before it could increment it, Thread2 reads the value and increments that. So thus, the result may be less than 20000. To solve this issue, we use the synchronized keyword. If the synchronized keyword is used while declaring the increment() method, then a thread needs to wait for another thread to complete the operation of the method then only another one can work on it. So we can get guaranteed output of 20000.
Below is the synchronized code:
Java
import java.io.*;
class Counter{
int count;
synchronized void increment(){
count++;
}
}
class GFG{
public static void main(String[] args) throws InterruptedException {
Counter c= new Counter();
Thread t1= new Thread( new Runnable() {
@Override
public void run() {
for ( int i= 1 ;i<= 100000 ;i++){
c.increment();
}
}
});
Thread t2= new Thread( new Runnable() {
@Override
public void run() {
for ( int i= 1 ;i<= 100000 ;i++){
c.increment();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(c.count);
}
}
|
volatile keyword only and only ensures that changes that are made to variables are reflected across all threads that are accessing the same variable/thread. The usage of volatile keywords does not guarantee thread safety for class but it does not ensure thread safety and concurrency issues. Hence if we want our class to be thread-safe then we need to invoke it via the below technologies:
- Using synchronized keyword
- Using monitors
- using concurrency techniques (language dependent)
Tip: The volatile keyword is only applicable to a variable.
Usage and Application: volatile keyword reduces the chance of memory inconsistency. The value of a volatile variable is always read from the main memory and not from the local thread cache, and it helps to improve thread performance.
Let us understand by an example:
Java
import java.io.*;
import java.util.*;
class Geeks extends Thread {
boolean running = true ;
@Override public void run()
{
while (running) {
System.out.println( "GeeksforGeeks" );
}
}
public void shutDown() { running = false ; }
}
class GFG {
public static void main(String[] args)
{
Geeks obj = new Geeks();
obj.start();
Scanner input = new Scanner(System.in);
input.nextLine();
obj.shutDown();
}
}
|
Output

In the above code, the program should ideally stop if Return Key/Enter is pressed, but in some machines, it may happen that the variable running is cached, and we are not able to change its value using the shutdown() method. In such a case, the program will execute infinite times and cannot be exited properly. To avoid caching and make it Thread-safe, we can use volatile keywords while declaring the running variable.
Java
import java.io.*;
import java.util.*;
class Geeks extends Thread
{
volatile boolean running = true ;
@Override public void run()
{
while (running) {
System.out.println( "GeeksforGeeks" );
}
}
public void shutDown() { running = false ; }
}
class GFG {
public static void main(String[] args)
{
Geeks obj = new Geeks();
obj.start();
Scanner input = new Scanner(System.in);
input.nextLine();
obj.shutDown();
}
}
|
Output:

In the above code, after using the volatile keyword, we can stop the infinite loop using the Return key, and the program exited properly with exit code 0.
This needs prior knowledge of serialization in Java. You can refer to the following article for that:- serialization in java.
The transient keyword may be applied to member variables of a class to indicate that the member variable should not be serialized when the containing class instance is serialized. Serialization is the ​process of converting an object into a byte stream. When we do not want to serialize the value of a variable, then we declare it as transient. To make it more transparent, let’s take an example of an application where we need to accept UserID and Password. At that moment, we need to declare some variable to take the input and store the data, but as the data is susceptible, we do not want to keep it stored after the job is done. To achieve this, we can use the transient keyword for variable declaration. That particular variable will not participate in the serialization process, and when we deserialize that, we will receive the default value of the variable.
Let us see a sample code for the same as follows:
Java
import java.io.*;
class transient_gfg implements Serializable {
int a = 10 ;
transient String UserID = "admin" ;
transient String Password = "tiger123" ;
}
class GFG {
public static void main(String[] args)
throws IOException, ClassNotFoundException
{
transient_gfg obj = new transient_gfg();
System.out.println( "UserID :" + obj.UserID);
System.out.println( "Password: " + obj.Password);
System.out.println( "a = " + obj.a);
FileOutputStream fos
= new FileOutputStream( "abc.txt" );
ObjectOutputStream oos
= new ObjectOutputStream(fos);
oos.writeObject(obj);
FileInputStream fis
= new FileInputStream( "abc.txt" );
ObjectInputStream ois = new ObjectInputStream(fis);
transient_gfg output
= (transient_gfg)ois.readObject();
System.out.println( "UserID :" + output.UserID);
System.out.println( "Password: " + output.Password);
System.out.println( "a = " + obj.a);
}
}
|
Output:

As you see from the output, after serialization, the values of UserID and Password are no longer present. However, the value of ‘a’, which is a normal variable, is still present.
The native keyword may be applied to a method to indicate that the method is implemented in a language other than Java. Using this java application can call code written in C, C++, or assembler language. A shared code library or DLL is required in this case.
Let us see an example first –
Java
import java.io.*;
class GFG {
public native void printMethod();
static
{
System.loadLibrary( "LibraryName" );
}
public static void main(String[] args)
{
GFG obj = new GFG();
obj.printMethod();
}
}
|
Output:

In the above code, we have a native method. The method is defined in any other language and loaded by a java application using the shared DLL file. Implementation of the DLL file is out of the scope of this article, so if you want to know more about it, you can refer to this article.
Multi-Language Programming – Java Process Class, JNI, and IO.
Similar Reads
Access Modifiers in Java
In Java, access modifiers are essential tools that define how the members of a class, like variables, methods, and even the class itself can be accessed from other parts of our program. They are an important part of building secure and modular code when designing large applications. Understanding de
7 min read
Access and Non Access Modifiers in Java
Java provides a rich set of modifiers. They are used to control access mechanisms and also provide information about class functionalities to JVM. They are divided into two categories namely: Access modifiersNon-access modifiers Access Modifiers Javaâs access modifiers are public, private, and prote
2 min read
Java - Final vs Static Access Modifier
The final keyword is used in different contexts. First, final is a non-access modifier applicable only to a variable, a method, or a class. The following are different contexts where the final is used. The static keyword in Java is mainly used for memory management. The static keyword in Java is use
6 min read
Access Modifiers in Scala
Access Modifiers in scala are used to define the access field of members of packages, classes or objects in scala.For using an access modifier, you must include its keyword in the definition of members of package, class or object.These modifiers will restrict accesses to the members to specific regi
3 min read
What Are Access Modifiers In JavaScript ?
Access modifiers in JavaScript play a significant role in controlling the visibility and accessibility of class members. Although JavaScript is not traditionally an object-oriented programming (OOP) language, the introduction of classes and access modifiers in ECMAScript 6 (ES6) allowed developers t
4 min read
Protected vs Package Access Modifiers in Java
Whenever we are writing our classes, we have to provide some information about our classes to the JVM like whether this class can be accessed from anywhere or not, whether child class creation is possible or not, whether object creation is possible or not, etc. we can specify this information by usi
4 min read
Protected vs Private Access Modifiers in Java
Access modifiers are those elements in code that determine the scope for that variable. As we know there are three access modifiers available namely public, protected, and private. Let us see the differences between Protected and Private access modifiers. Access Modifier 1: Protected The methods or
2 min read
Public vs Private Access Modifiers in Java
Whenever we are writing our classes we have to provide some information about our classes to the JVM like whether this class can be accessible from anywhere or not, whether child class creation is possible or not, whether object creation is possible or not etc. we can specify this information by usi
3 min read
Protected vs Final Access Modifier in Java
Whenever we are writing our classes, we have to provide some information about our classes to the JVM like whether this class can be accessed from anywhere or not, whether child class creation is possible or not, whether object creation is possible or not, etc. we can specify this information by usi
5 min read
Private vs Final Access Modifier in Java
Whenever we are writing our classes we have to provide some information about our classes to the JVM like whether this class can be accessed from anywhere or not, whether child class creation is possible or not, whether object creation is possible or not etc. we can specify this information by using
3 min read