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 46 of 59
←PreviousPrevNextNext→

Java Modifiers - Complete Guide

Introduction to Java Modifiers

Java modifiers are keywords that provide information about the accessibility, scope, and behavior of classes, methods, variables, and other elements. They are essential for implementing encapsulation, inheritance, and other object-oriented principles.

Understanding Java modifiers is crucial for writing secure, maintainable, and well-structured code that follows object-oriented design principles.

Access Modifiers

Access modifiers control the visibility and accessibility of classes, methods, and variables in Java. They determine which other classes can access the modified element.

Example
// File 1: AccessModifiersDemo.java
public class AccessModifiersDemo {
    public String publicField = "Public Field";
    protected String protectedField = "Protected Field";
    String defaultField = "Default Field"; // package-private
    private String privateField = "Private Field";

    public void publicMethod() { System.out.println("Public Method"); }
    protected void protectedMethod() { System.out.println("Protected Method"); }
    void defaultMethod() { System.out.println("Default Method"); }
    private void privateMethod() { System.out.println("Private Method"); }

    public void demonstrateAccess() {
        System.out.println("=== Access within same class ===");
        System.out.println(publicField);
        System.out.println(protectedField);
        System.out.println(defaultField);
        System.out.println(privateField);

        publicMethod();
        protectedMethod();
        defaultMethod();
        privateMethod();
    }

    public static void main(String[] args) {
        AccessModifiersDemo demo = new AccessModifiersDemo();
        demo.demonstrateAccess();
        System.out.println("\n=== Access from same package ===");
        SamePackageAccess.testAccess();
    }
}

// File 2: SamePackageAccess.java (same package)
class SamePackageAccess {
    public static void testAccess() {
        AccessModifiersDemo demo = new AccessModifiersDemo();
        System.out.println(demo.publicField);
        System.out.println(demo.protectedField);
        System.out.println(demo.defaultField);
        demo.publicMethod();
        demo.protectedMethod();
        demo.defaultMethod();
        // Private members not accessible here
    }
}

// File 3: DifferentPackageAccess.java (different package)
/*
package anotherpackage;
import originalpackage.AccessModifiersDemo;

public class DifferentPackageAccess {
    public static void testAccess() {
        AccessModifiersDemo demo = new AccessModifiersDemo();
        System.out.println(demo.publicField);
        demo.publicMethod();
        // protected, default, and private are not accessible
    }
}

// File 4: SubclassInDifferentPackage.java (different package)
package anotherpackage;
import originalpackage.AccessModifiersDemo;

public class SubclassInDifferentPackage extends AccessModifiersDemo {
    public void testAccess() {
        System.out.println(publicField);
        System.out.println(protectedField); // accessible via inheritance
        publicMethod();
        protectedMethod();
        // default and private not accessible
    }
}
*/
Output
=== Access within same class ===
Public Field
Protected Field
Default Field
Private Field
Public Method
Protected Method
Default Method
Private Method

=== Access from same package ===
Public Field
Protected Field
Default Field
Public Method
Protected Method
Default Method

Non-Access Modifiers

Non-access modifiers provide additional functionality and behavior control for classes, methods, and variables beyond just accessibility.

Example
public class NonAccessModifiers {
    public final int MAX_VALUE = 100; // constant value
    public static int instanceCount = 0; // shared across instances
    private transient String temporaryData; // not serialized
    private volatile boolean running = true; // for multithreading

    public final void finalMethod() {
        System.out.println("This method cannot be overridden");
    }

    public static void staticMethod() {
        System.out.println("Static method called");
        System.out.println("Instance count: " + instanceCount);
    }

    public synchronized void synchronizedMethod() {
        System.out.println("Synchronized method - thread safe");
    }

    public NonAccessModifiers() { instanceCount++; }

    public void testFinal() { System.out.println("MAX_VALUE: " + MAX_VALUE); }

    public void showInstanceCount() {
        System.out.println("This is instance " + instanceCount);
    }

    public static void main(String[] args) {
        System.out.println("=== Non-Access Modifiers Demo ===\n");
        NonAccessModifiers.staticMethod();
        NonAccessModifiers obj1 = new NonAccessModifiers();
        NonAccessModifiers obj2 = new NonAccessModifiers();

        System.out.println("\n=== Final Variable ===");
        obj1.testFinal();

        System.out.println("\n=== Static Variable ===");
        obj1.showInstanceCount();
        obj2.showInstanceCount();
        System.out.println("Total instances: " + NonAccessModifiers.instanceCount);

        System.out.println("\n=== Final Method ===");
        obj1.finalMethod();

        System.out.println("\n=== Synchronized Method ===");
        obj1.synchronizedMethod();

        System.out.println("\n=== Volatile Variable ===");
        System.out.println("Running: " + obj1.running);
        obj1.running = false;
        System.out.println("Running after change: " + obj1.running);
    }
}

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

abstract class AbstractClass {
    public void concreteMethod() { System.out.println("This is a concrete method"); }
    public abstract void abstractMethod();
}

class ConcreteClass extends AbstractClass {
    @Override
    public void abstractMethod() { System.out.println("Implemented abstract method"); }
}

class AbstractDemo {
    public static void main(String[] args) {
        ConcreteClass obj = new ConcreteClass();
        obj.concreteMethod();
        obj.abstractMethod();
    }
}
Output
=== Non-Access Modifiers Demo ===

Static method called
Instance count: 0

=== Final Variable ===
MAX_VALUE: 100

=== Static Variable ===
This is instance 2
This is instance 2
Total instances: 2

=== Final Method ===
This method cannot be overridden

=== Synchronized Method ===
Synchronized method - thread safe

=== Volatile Variable ===
Running: true
Running after change: false

Best Practices for Java Modifiers

  • ✅ Use the most restrictive access level that makes sense for each member
  • ✅ Prefer private fields with public getters/setters for encapsulation
  • ✅ Use final for variables that shouldn't change and methods that shouldn't be overridden
  • ✅ Use static for class-level utility methods and constants
  • ✅ Use synchronized for methods that access shared resources in multithreaded environments
  • ✅ Consider using volatile for flags and status variables in multithreading
  • ✅ Use abstract classes and methods to define contracts for subclasses
  • ✅ Be consistent with modifier usage throughout your codebase
Test your knowledge: Java Modifiers - Complete Guide
Quiz Configuration
4 of 10 questions
Sequential
Previous allowed
Review enabled
Early close allowed
Estimated time: 5 min
Java OOPTopic 46 of 59
←PreviousPrevNextNext→