DevAcademia
C++C#CPythonJava
  • Java Basics

  • Java Introduction
  • Java Get Started
  • Java Syntax
  • Java Output
  • Java Comments
  • Java Variables
  • Java Data Types
  • Java Type Casting
  • Java Operators
  • Java Strings
  • Java If...Else
  • Java Switch Statement
  • Java Loops
  • Java Math
  • Java Arrays
  • Java Date
  • Java OOP

  • Java Classes/Objects
  • Java Class Attributes
  • Java Class Methods
  • Java Constructors
  • Java Destructors
  • Java this Keyword
  • Java Modifiers
  • Java Non Modifiers
  • Java Encapsulation
  • Java Packages & API
  • Java Inheritance
  • Java Polymorphism
  • Java Super Keyword
  • Java Inner Classes
  • Java Exception Handling
  • Java Abstraction
  • Java Interfaces
  • Java Enums
  • Java User Input
  • Java Quiz

  • Java Fundamentals Quiz
  • Java Basics

  • Java Introduction
  • Java Get Started
  • Java Syntax
  • Java Output
  • Java Comments
  • Java Variables
  • Java Data Types
  • Java Type Casting
  • Java Operators
  • Java Strings
  • Java If...Else
  • Java Switch Statement
  • Java Loops
  • Java Math
  • Java Arrays
  • Java Date
  • Java OOP

  • Java Classes/Objects
  • Java Class Attributes
  • Java Class Methods
  • Java Constructors
  • Java Destructors
  • Java this Keyword
  • Java Modifiers
  • Java Non Modifiers
  • Java Encapsulation
  • Java Packages & API
  • Java Inheritance
  • Java Polymorphism
  • Java Super Keyword
  • Java Inner Classes
  • Java Exception Handling
  • Java Abstraction
  • Java Interfaces
  • Java Enums
  • Java User Input
  • Java Quiz

  • Java Fundamentals Quiz

Loading Java tutorial…

Loading content
Java OOPTopic 47 of 59
←PreviousPrevNextNext→

Java Non-Access Modifiers

Introduction to Non-Access Modifiers

Non-access modifiers in Java define the behavior and additional properties of classes, methods, and variables beyond visibility (public, private, etc.).

They control aspects like memory allocation, inheritance, thread-safety, and serialization. Common non-access modifiers include `static`, `final`, `abstract`, `synchronized`, `transient`, and `volatile`.

Common Non-Access Modifiers

ModifierApplied ToPurpose
staticVariables, Methods, BlocksShared across all instances; belongs to the class
finalVariables, Methods, ClassesPrevents reassignment, overriding, or inheritance
abstractClasses, MethodsDefines incomplete functionality to be implemented by subclasses
synchronizedMethods, BlocksEnsures thread-safe execution by allowing one thread at a time
transientVariablesExcludes the field from serialization
volatileVariablesGuarantees visibility of changes across threads

Static Modifier

The `static` keyword makes a field or method belong to the class instead of specific objects.

Static variables are shared across all instances, and static methods can be invoked without creating an object.

Example
public class Counter {
    static int count = 0;

    Counter() {
        count++;
    }

    static void displayCount() {
        System.out.println("Total count: " + count);
    }

    public static void main(String[] args) {
        new Counter();
        new Counter();
        new Counter();
        Counter.displayCount();
    }
}
Output
Total count: 3

Final Modifier

The `final` keyword ensures immutability in certain contexts:

- A final variable becomes a constant and cannot be reassigned.

- A final method cannot be overridden.

- A final class cannot be extended.

Example
final class MathConstants {
    public static final double PI = 3.14159;

    public final void displayPI() {
        System.out.println("PI value: " + PI);
    }
}

public class Example {
    public static void main(String[] args) {
        System.out.println("PI: " + MathConstants.PI);
    }
}
Output
PI: 3.14159

Abstract Modifier

The `abstract` keyword is used for declaring abstract classes and methods.

- Abstract classes cannot be instantiated directly.

- Abstract methods have no body and must be implemented by subclasses.

Example
abstract class Shape {
    abstract double area();

    public void display() {
        System.out.println("This is a shape");
    }
}

class Circle extends Shape {
    double radius;

    Circle(double r) {
        radius = r;
    }

    double area() {
        return Math.PI * radius * radius;
    }
}

public class Test {
    public static void main(String[] args) {
        Shape circle = new Circle(5.0);
        System.out.println("Area: " + circle.area());
    }
}
Output
Area: 78.53981633974483

Synchronized Modifier

The `synchronized` keyword ensures that only one thread at a time can execute a method or block, preventing race conditions when accessing shared mutable state.

Example
class SyncCounter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

public class SyncDemo {
    public static void main(String[] args) throws InterruptedException {
        SyncCounter counter = new SyncCounter();

        Runnable task = () -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        };

        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);
        t1.start();
        t2.start();
        t1.join();
        t2.join();

        System.out.println("Final Count: " + counter.getCount());
    }
}
Output
Final Count: 2000

Transient Modifier

The `transient` keyword marks a variable as non-serializable. When an object is serialized, transient fields are skipped.

Example
import java.io.*;

class User implements Serializable {
    String name;
    transient String password;

    User(String n, String p) {
        name = n;
        password = p;
    }
}

public class TransientDemo {
    public static void main(String[] args) throws Exception {
        User u = new User("Alice", "secret123");

        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.ser"));
        out.writeObject(u);
        out.close();

        ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.ser"));
        User restored = (User) in.readObject();
        in.close();

        System.out.println("Name: " + restored.name);
        System.out.println("Password: " + restored.password);
    }
}
Output
Name: Alice
Password: null

Volatile Modifier

The `volatile` keyword ensures that changes to a variable are always visible to all threads. It prevents threads from caching the variable locally.

Example
class SharedData {
    volatile boolean running = true;

    public void stop() {
        running = false;
    }
}

public class VolatileDemo {
    public static void main(String[] args) throws InterruptedException {
        SharedData data = new SharedData();

        Thread worker = new Thread(() -> {
            while (data.running) {
                // busy wait
            }
            System.out.println("Stopped!");
        });

        worker.start();
        Thread.sleep(1000);
        data.stop();
    }
}
Output
Stopped!

Best Practices

  • ✅ Use `static` for utility methods and constants shared across objects
  • ✅ Use `final` for constants and to prevent unintended modifications or subclassing
  • ✅ Use `abstract` to define contracts for subclasses to implement
  • ✅ Use `synchronized` only when necessary to avoid performance bottlenecks
  • ✅ Use `transient` for fields that should not be serialized
  • ✅ Use `volatile` for variables shared by multiple threads where visibility is critical
Test your knowledge: Java Non-Access Modifiers
Quiz Configuration
4 of 8 questions
Sequential
Previous allowed
Review enabled
Early close allowed
Estimated time: 5 min
Java OOPTopic 47 of 59
←PreviousPrevNextNext→