OOP

28. Access Modifiers

Java has four access levels — public, protected, package-private (no keyword), and private — controlling visibility of classes, fields, methods, and constructors across packages and inheritance hierarchies.

Java 21 (core language)

Explanation

| Modifier | Same class | Same package | Subclass (any pkg) | Any class | |---|---|---|---|---| | private | ✓ | ✗ | ✗ | ✗ | | package-private | ✓ | ✓ | ✗ | ✗ | | protected | ✓ | ✓ | ✓ | ✗ | | public | ✓ | ✓ | ✓ | ✓ |

Design guidance: default to private for fields (encapsulation), use public only for intentional API surface, and reserve protected for hook methods in abstract classes intended for subclassing. Minimise the access level: start private and open up only as needed.

Note: top-level classes can only be public or package-private. Inner/nested classes and members support all four. Modules (Java 9+) add another layer — public inside a module is not accessible outside unless the package is exports-ed.

Example

package com.example; // assume this package

public class AccessDemo {
    private   int privateField   = 1; // only this class
    /* pkg */ int packageField   = 2; // same package
    protected int protectedField = 3; // same pkg + subclasses
    public    int publicField    = 4; // everywhere

    private   void privateMethod()   { System.out.println("private");   }
    /* pkg */ void packageMethod()   { System.out.println("package");   }
    protected void protectedMethod() { System.out.println("protected"); }
    public    void publicMethod()    { System.out.println("public");    }

    // Fields should be private — expose via methods
    private String name;
    public  String getName()          { return name; }
    public  void   setName(String n)  { this.name = n; }

    public static void main(String[] args) {
        AccessDemo obj = new AccessDemo();
        obj.privateMethod();   // OK — same class
        obj.packageMethod();   // OK — same class
        obj.protectedMethod(); // OK — same class
        obj.publicMethod();    // OK — same class

        System.out.println("Private:   " + obj.privateField);
        System.out.println("Package:   " + obj.packageField);
        System.out.println("Protected: " + obj.protectedField);
        System.out.println("Public:    " + obj.publicField);
    }
}

Sources