Java Access Modifiers
Java modifiers are keywords that define the scope, visibility, and behavior of a class, method, or variable. They are essential to the Java programming language and control access to various program elements. Understanding Java modifiers is crucial for any developer who wants to write clean, efficient, and secure code.
This article will discuss the different types of Java modifiers, their usage, and examples of each. We will explore some best practices for using Java modifiers in your code.
Java Modifiers - Introduction
In Java, a modifier is a keyword that provides additional information about a class, method, or variable. Modifiers can control access to classes, methods, and variables and modify their behavior and characteristics.
Java has two types of modifiers: Access modifiers and Non-access modifiers.
Access modifiers control the visibility of classes, methods, and variables. They determine which other classes can access a particular element of a program. There are four access modifiers in Java:
- Public
- Private
- Protected
- Default
Non-access modifiers do not control visits but modify the behavior and characteristics of classes, methods, and variables. There are several non-access modifiers in Java:
- Static
- Final
- Abstract
- Synchronized
- Transient
- Volatile
- Native
- Strictfp
In the following sections, we will discuss each modifier in detail.
Public Modifier
Any class, regardless of location, can access a class, method, or variable when marked as public. This modification makes the public component of a prprogramccessible to other classes.
Example:
public class MyClass {
public void method() {
System.out.println("Hello World!");
}
}
In the above example, the class MyClass is declared as public. This means that any other class can access the MyClass class. The method myMethod() is also declared public, which means that any other class can call this method.
Private Modifier
A class, method, or variable can only be accessed within the class in which they are declared using the private modifier. This modification prevents other classes from accessing a program's private component.
Example:
public class MyClass {
private int myVar;
private void myMethod() {
System.out.println("Hello World!");
}
}
In the above example, the variable myVar and the method myMethod() are declared private. This means that they can only be accessed within the MyClass class.
Protected Modifier
The protected modifier is used to make a class, method, or variable available to any subclass of the class in which it is declared and inside the same package.
Example:
public class MyClass {
protected int myVar;
protected void myMethod() {
System.out.println("Hello World!");
}
}
In the above example, the variable myVar and the method myMethod() are declared protected. This means they can be accessed within the same package and by any subclass of the MyClass class.
Default Modifier
A class, method, or variable that hawithodifier is only available inside the same package. It also goes by the name "package-private." When no access modifier is supplied, the default modifier is applied.
Example:
class MyClass {
int myVar;
void myMethod() {
System.out.println("Hello World!");
}
}
The class MyClass is declared without any access modifier in the above example. This means it is package private and can only be accessed within the same package.
Program for different access modifiers in Java
AccessModifiers.java
class AccessModifiers
{
public int publicVar = 5;
private int privateVar = 10;
protected int protectedVar = 15;
int defaultVar = 20;
public void publicMethod() {
System.out.println("This is a public method");
}
private void privateMethod() {
System.out.println("This is a private method");
}
protected void protectedMethod() {
System.out.println("This is a protected method");
}
void defaultMethod() {
System.out.println("This is a default method");
}
public static void main(String[] args) {
AccessModifiers myObj = new AccessModifiers ();
System.out.println("Public variable value: " + myObj.publicVar);
System.out.println("Private variable value: " + myObj.privateVar); // This will cause a compile-time error
System.out.println("Protected variable value: " + myObj.protectedVar);
System.out.println("Default variable value: " + myObj.defaultVar);
myObj.publicMethod();
myObj.privateMethod(); // This will cause a compile-time error
myObj.protectedMethod();
myObj.defaultMethod();
}
}
Output
Public variable value: 5
Private variable value: 10
Protected variable value: 15
Default variable value: 20
This is a public method
This is a private method
This is a protected method
This is a default method
Non-Access Modifier
1. Static Modifier
Use the term to declare variables, methods, and nested classes ". The static modifier is used in Java to create class-level variables, methods, and nested classes that can be accessed without creating an instance of the class. A static initializer block is likewise created using the static keyword, and it is then run when the class is loaded.
Static Variables
A static variable is a class-level variable shared among all instances of class instances class is loaded. Its value is the same for all class instances. Static variables are accessed using the class name followed by the variable name.
MyClass.java
public class MyClass {
static int myVar = 10;
public static void main(String[] args) {
System.out.println(MyClass.myVar); // output: 10
MyClass.myVar = 20;
System.out.println(MyClass.myVar); // output: 20
}
}
Output
10
20
Static Methods
It is possible to access a static method at the class level without first generating an instance of the class. It is utilized when a method does not require access to instance-level variables, and methods class name and the method name are used to access static methods.
public class MyClass {
static void myStaticMethod() {
System.out.println("Hello World!");
}
public static void main(String[] args) {
MyClass.myStaticMethod(); // output: Hello World!
}
}
Output
Hello World!
In the above example, the method myStaticMethod() is declared static, meaning it is a class-level method. The method is accessed using the class name MyClass.myStaticMethod().
Static Nested Classes
A static nested class is a class that is declared inside another class and is accessed using the outer class name. It is used when the nested class cannot access instance-level variables and methods. A static nested class is accessed using the outer class name, followed by the nested class name.
MyClass.java
public class MyClass {
static class MyNestedClass {
public void myMethod() {
System.out.println("Hello World!");
}
}
public static void main(String[] args) {
MyClass.MyNestedClass myObject = new MyClass.MyNestedClass();
myObject.myMethod(); // output: Hello World!
}
}
Output
Hello World!
In the above example, the class MyNestedClass is declared a static nested class inside the class MyClass. The class is accessed using the outer class name MyClass.MyNestedClass.
Static Initializer Block
When a class is loaded, a section of code known as a static initialiser block is run. When the class is loaded, it is used to initialise static variables and perform additional initialisation procedures. The static keyword defines a static initialiser block, followed by curly braces.
MyClass.java
public class MyClass {
static int myVar;
static {
myVar = 10;
}
public static void main(String[] args) {
System.out.println(MyClass.myVar); // output: 10
}
}
Output
10
The example above uses the static initialiser block to initialize the variable myVar to 10. The class name MyClass.myVar may be used to access the variable myVar, and the static initialiser block is run when the class is loaded.
Final Modifier
The final modifier indicates that the method, or via viable, cannot be changed once it has been initialised. A final class cannot be subclassed, and a final method cannot be overridden. A final variable is also called a constant in Java, and its value cannot be modified once it is initialized.
Example:
MyClass.java
public class MyClass {
final int myVar = 10;
public final void myMethod() {
System.out.println("Hello World!");
}
}
In the above example, the variable myVar is declared as final, which means its value cannot be changed once it is initialised. The method myMethod() is also declared as final, which means it cannot be overridden by any subclass of the MyClass class.
Abstract Modifier
The abstract modifier indicates that a class or method does not have an implementation and must be defined by a subclass. A base class for other classes is an abstract class, which cannot be instantiated. The methods that a subclass must specify are placed in an abstract method, which lacks a body.
Example:
public abstract class MyAbstractClass {
public abstract void myMethod();
}
public class MyClass extends MyAbstractClass {
public void myMethod() {
System.out.println("Hello World!");
}
}
In the above example, the class MyAbstractClass is declared abstract and has an abstract method myMethod(). The class MyClass extends MyAbstractClass and provides an implementation for the myMethod() method.
Synchronized Modifier
A function or block of code may only be accessed by one thread at a time thanks to the synchronized modifier. The ability for several threads to access the same object or resource at once makes this valuable in multithreaded programming.
Example
public class MyClass {
public synchronized void myMethod() {
// Code to be executed by only one thread at a time
}
}
In the above example, the method myMethod() is declared synchronise only one thread can execute this method at a time. This is useful when multiple threads are accessed with the same object or resource and avoids concurrency issues.
Transient Modifier
Serialisation converts an object into a stream of bytes for storage or transmission. When an object is deserialised is recreated from the serialised stream of bytes. The transient modifier indicates that a variable should not be serialiserializedhe object is serialised.
Example:
public class MyClass implements Serializable {
transient int myVar;
}
In the above example, the variable myVar is declared transient, which means it will not be serialized if the object of the MyClass class is serialised.
Volatile Modifier
The volatile modifier indicates that multiple threads may modify a variable's value. This modifier ensures that the variable's value is always up-to-date and that changes to the variable's value are immediately visible to all threads.
Example
public class MyClass {
volatile int myVar;
}
In the above example, the variable myVar is declared volatile, meaning multiple threads may modify its value.
Modifiers for nested classes' access
A class can nest inside another class in Java. If a class is nested inside another class and is a static or non-static nested class will affect the meaning of its access modifiers. In contrast to static nested classes, non-static nested classes, also known as inner classes, have access to the private members of the surrounding class.
Modifiers of access for constructors
Special methods called constructors are used to generate instances of classes. Like other class members, constructors can have access modifiers that regulate their external visibility. For instance, a private function Object() can stop outside code from generating instances of a class.
Interface access modifiers
In Java, interfaces are forms of reference data that specify a collection of method signatures that implementing classes must implement. Access modifiers are permitted for interface methods and constants but not for the entire group of interface members.
Modifiers for access and inheritance
A key idea in object-oriented programming is inheritance, where a subclass takes on the traits and capabilities of its superclass. Access modifiers are crucial in the inheritance because they regulate the visibility of members of the superclass in the subclass. A subclass can access protected and public members of its superclass but not private members.
Program for Java Modifiers List
public class JavaModifiers {
public static void main(String[] args) {
//Accessing Public Modifier
PublicModifier publicModifier = new PublicModifier();
System.out.println("Public Modifier Output: " + publicModifier.publicVar);
//Accessing Private Modifier
PrivateModifier privateModifier = new PrivateModifier();
//System.out.println("Private Modifier Output: " + privateModifier.privateVar); //Cannot access private field outside the class
//Accessing Protected Modifier
ProtectedModifier protectedModifier = new ProtectedModifier();
//System.out.println("Protected Modifier Output: " + protectedModifier.protectedVar); //Cannot access protected field outside the package
//Accessing Default Modifier
DefaultModifier defaultModifier = new DefaultModifier();
System.out.println("Default Modifier Output: " + defaultModifier.defaultVar);
//Accessing Static Modifier
System.out.println("Static Modifier Output: " + StaticModifier.staticVar);
//Accessing Final Modifier
FinalModifier finalModifier = new FinalModifier();
//finalModifier.finalVar = 20; //Cannot modify the final field value
System.out.println("Final Modifier Output: " + finalModifier.finalVar);
//Accessing Abstract Modifier
AbstractModifier abstractModifier = new ConcreteClass();
abstractModifier.abstractMethod();
//Accessing Synchronized Modifier
SynchronizedModifier synchronizedModifier = new SynchronizedModifier();
synchronized (synchronizedModifier) {
synchronizedModifier.synchronizedMethod();
}
//Accessing Volatile Modifier
VolatileModifier volatileModifier = new VolatileModifier();
Thread t1 = new Thread(volatileModifier);
Thread t2 = new Thread(volatileModifier);
t1.start();
t2.start();
//Accessing Transient Modifier
TransientModifier transientModifier = new TransientModifier();
System.out.println("Transient Modifier Output: " + transientModifier.transientVar);
/*
//Accessing Strictfp Modifier
StrictfpModifier strictfpModifier = new StrictfpModifier();
strictfpModifier.strictfpMethod();
//Accessing Native Modifier
NativeModifier nativeModifier = new NativeModifier();
nativeModifier.nativeMethod();
*/
}
}
//Public Modifier
class PublicModifier {
public int publicVar = 10;
}
//Private Modifier
class PrivateModifier {
private int privateVar = 20;
}
//Protected Modifier
class ProtectedModifier {
protected int protectedVar = 30;
}
//Default Modifier
class DefaultModifier {
int defaultVar = 40;
}
//Static Modifier
class StaticModifier {
static int staticVar = 50;
}
//Final Modifier
class FinalModifier {
final int finalVar = 60;
}
//Abstract Modifier
abstract class AbstractModifier {
abstract void abstractMethod();
}
//Concrete Class for Abstract Modifier
class ConcreteClass extends AbstractModifier {
@Override
void abstractMethod() {
System.out.println("Abstract Modifier Output");
}
}
//Synchronized Modifier
class SynchronizedModifier {
synchronized void synchronizedMethod() {
System.out.println("Synchronized Modifier Output");
}
}
//Volatile Modifier
class VolatileModifier implements Runnable {
volatile int volatileVar = 70;
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Volatile Modifier Output: " + volatileVar++);
}
}
}
//Transient Modifier
class TransientModifier implements java.io.Serializable {
transient int transientVar = 80;
}
Output
Public Modifier Output: 10
Default Modifier Output: 40
Static Modifier Output: 50
Final Modifier Output: 60
Abstract Modifier Output
Synchronized Modifier Output
Volatile Modifier Output: 70
Volatile Modifier Output: 71
Volatile Modifier Output: 73
Volatile Modifier Output: 72
Volatile Modifier Output: 74
Volatile Modifier Output: 75
Transient Modifier Output: 80
Volatile Modifier Output: 76
Volatile Modifier Output: 77
Volatile Modifier Output: 78
Volatile Modifier Output: 79
Volatile Modifier Output: 80
Volatile Modifier Output: 81
Volatile Modifier Output: 83
Volatile Modifier Output: 82
Volatile Modifier Output: 84
Volatile Modifier Output: 86
Volatile Modifier Output: 85
Volatile Modifier Output: 87
Volatile Modifier Output: 88
Volatile Modifier Output: 89