← Back to Home

Access Modifiers

Access modifiers in Java control the visibility and accessibility of classes, variables, methods, and constructors. They are a core mechanism for encapsulation, security, and clean API design. This is a must-know interview topic and heavily used in real-world Java projects.

What Are Access Modifiers?

  • Keywords that define where a member can be accessed from
  • Enforce data hiding and controlled exposure
  • Applied to classes, methods, variables, and constructors

Types of Access Modifiers in Java

Java provides four access levels:

  1. private
  2. default (no keyword)
  3. protected
  4. public

Access Level Hierarchy (Least → Most Accessible)

private < default < protected < public
          

1. private

  • Accessible only within the same class
  • Most restrictive
  • Commonly used for instance variables
class Student {
    private int age;

    private void calculate() { }
}
          
  • ✔ Supports strong encapsulation
  • ❌ Not accessible outside the class

2. default (Package-Private)

  • No keyword used
  • Accessible within the same package only
  • Not accessible from outside the package
class Student {
    int marks; // default access
}
          
  • ✔ Useful for package-level collaboration
  • ❌ No access across packages

3. protected

  • Accessible within the same package
  • Accessible in subclasses, even in different packages
class Parent {
    protected int value;
}
          
  • ✔ Useful in inheritance
  • ✔ Common in framework design

4. public

  • Accessible from anywhere
  • Least restrictive
  • Used for APIs, entry points, and services
public class Student {
    public void display() { }
}
          
  • ✔ Required for main() method
  • ✔ Used for externally exposed functionality

Access Modifiers Visibility Table (Interview Favorite)

Access Modifier Same Class Same Package Subclass (diff pkg) Everywhere
private
default
protected
public

Access Modifiers with Class Declaration

Top-Level Classes

  • Only public and default are allowed
public class Test { }
class Helper { } // default
          

❌ private and protected are not allowed for top-level classes.

Access Modifiers with Constructors

class Example {
    private Example() { }   // restrict object creation
    public Example(int x) { }
}
          
  • ✔ Used in Singleton pattern
  • ✔ Controls object creation

Access Modifiers and Encapsulation (Best Practice)

class Account {
    private double balance;

    public double getBalance() {
        return balance;
    }

    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }
}
          
  • Data hidden
  • Controlled access
  • Business rules enforced

Common Beginner Mistakes

  • Making variables public
  • Confusing protected with default
  • Assuming protected means package-only
  • Overexposing internal methods
  • Not understanding package boundaries

Interview-Ready Answers

Short Answer

Access modifiers control the visibility of classes, variables, and methods in Java.

Detailed Answer

Java provides four access modifiers: private, default, protected, and public. They define where a class member can be accessed from and are essential for encapsulation, security, and maintainable object-oriented design.

Key Takeaway

Use the most restrictive access level possible. Good access control leads to secure, maintainable, and flexible Java applications.

Access Modifiers Examples (Interview Friendly)

1. private – Accessible Only Within Same Class

class Demo {
    private int x = 10;

    private void show() {
        System.out.println(x);
    }

    public static void main(String[] args) {
        Demo d = new Demo();
        d.show();
    }
}
          

Explanation

private members accessible only inside the same class

Output: 10

2. private Not Accessible Outside Class

class A {
    private int x = 10;
}

class B {
    public static void main(String[] args) {
        A a = new A();
        // System.out.println(a.x); // Compile-time error
    }
}
          

Explanation

Even same package cannot access private

3. Default (No Modifier) – Package-Private Access

class A {
    int x = 10;   // default access
}

class B {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.x);
    }
}
          

Explanation

Accessible within same package

Output: 10

4. Default Access – Not Visible Outside Package

// package p1;
class A {
    int x = 10;
}

// package p2;
class B {
    public static void main(String[] args) {
        // new A().x; // Compile-time error
    }
}
          

Explanation

Default access is package-level only

5. public – Accessible Everywhere

public class A {
    public int x = 10;
}

class B {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.x);
    }
}
          

Explanation

public has no access restriction

Output: 10

6. protected – Same Package Access

class A {
    protected int x = 10;
}

class B {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.x);
    }
}
          

Explanation

protected works like default inside same package

Output: 10

7. protected – Access via Inheritance (Different Package)

// package p1;
class A {
    protected int x = 10;
}

// package p2;
class B extends A {
    public static void main(String[] args) {
        B b = new B();
        System.out.println(b.x);
    }
}
          

Explanation

protected accessible through inheritance

Output: 10

8. protected Not Accessible via Object (Different Package)

// package p1;
class A {
    protected int x = 10;
}

// package p2;
class B {
    public static void main(String[] args) {
        A a = new A();
        // System.out.println(a.x); // Compile-time error
    }
}
          

Explanation

Must use subclass reference, not parent object

9. Access Modifiers on Methods

class A {
    protected void show() {
        System.out.println("Protected Method");
    }
}

class B extends A {
    public static void main(String[] args) {
        new B().show();
    }
}
          

Explanation

Same rules apply to methods

Output: Protected Method

10. Overriding Method – Cannot Reduce Visibility

class A {
    protected void show() {}
}

class B extends A {
    // void show() {} // Compile-time error (cannot reduce visibility)
}
          

Explanation

Overridden method must be same or more accessible

11. Increasing Visibility While Overriding

class A {
    protected void show() {
        System.out.println("A");
    }
}

class B extends A {
    public void show() {
        System.out.println("B");
    }

    public static void main(String[] args) {
        new B().show();
    }
}
          

Explanation

Visibility increased (protected → public)

Output: B

12. Access Modifiers with Constructors

class A {
    private A() {
        System.out.println("Private Constructor");
    }

    public static void main(String[] args) {
        new A();
    }
}
          

Explanation

Constructor can be private

Used in Singleton pattern

13. private Constructor Prevents Object Creation

class A {
    private A() {}
}

class B {
    public static void main(String[] args) {
        // new A(); // Compile-time error
    }
}
          

Explanation

Object creation blocked outside class

14. Access Modifiers with Variables (Encapsulation)

class User {
    private int age;

    public int getAge() {
        return age;
    }
}
          

Explanation

Encapsulation uses private + public methods

15. Class-Level Access Modifiers

public class A {}

// protected class B {} // ❌ not allowed
// private class C {}   // ❌ not allowed
          

Explanation

Top-level classes can be only public or default

16. Nested Class Access Modifiers

class Outer {
    private class Inner {
        void show() {
            System.out.println("Inner");
        }
    }

    void call() {
        new Inner().show();
    }

    public static void main(String[] args) {
        new Outer().call();
    }
}
          

Explanation

Inner classes can be private

Output: Inner

17. Access Modifier Matrix (Conceptual)

/*
Modifier     Same Class  Same Package  Subclass  Other Package
private         ✔            ✘            ✘           ✘
default         ✔            ✔            ✘           ✘
protected       ✔            ✔            ✔           ✘*
public          ✔            ✔            ✔           ✔
*/
          

Explanation

protected across packages only via inheritance

18. Access Modifiers and Static Members

class A {
    protected static int x = 10;
}

class B extends A {
    public static void main(String[] args) {
        System.out.println(x);
    }
}
          

Explanation

Same access rules apply to static members

Output: 10

19. Common Interview Trap

class A {
    protected int x = 10;
}

class B {
    void test() {
        A a = new A();
        // System.out.println(a.x); // error if different package
    }
}
          

Explanation

protected ≠ public across packages

20. Interview Summary – Access Modifiers

class Demo {
    private int a = 10;
    int b = 20;
    protected int c = 30;
    public int d = 40;
}
          

Explanation

private → class only

default → package

protected → package + subclass

public → everywhere