Skip to content

Java Access Modifiers

Java access modifiers control visibility and accessibility of classes, fields, methods, and constructors. They are a core part of encapsulation, helping developers design maintainable, secure, and modular code.


1. What Are Access Modifiers?

Access modifiers determine who can access a class, method, or variable.

Java has four access levels:

ModifierClassPackageSubclassWorld (anywhere)
private
default (no keyword)
protected
public

2. Access Modifiers for Classes

Top-level classes

  • Can only be public or default (no modifier)
  • Default: accessible only within the same package
java
// Default access
class DefaultClass {}

// Public access
public class PublicClass {}

Inner/Nested classes

  • Can be private, default, protected, or public
  • Static nested classes vs non-static inner classes differ in usage
java
public class Outer {
    private class PrivateInner {}   // Only inside Outer
    public class PublicInner {}     // Accessible anywhere Outer is accessible
}

3. Access Modifiers for Fields and Methods

ModifierFields/Methods Accessibility
privateOnly within the class
defaultWithin the package
protectedPackage + subclasses
publicEverywhere
java
public class AccessExample {
    private int privateVar = 1;      // Only this class
    int defaultVar = 2;              // Only this package
    protected int protectedVar = 3;   // Package + subclasses
    public int publicVar = 4;         // Everywhere

    private void privateMethod() { System.out.println("private"); }
    void defaultMethod() { System.out.println("default"); }
    protected void protectedMethod() { System.out.println("protected"); }
    public void publicMethod() { System.out.println("public"); }
}

4. Access Modifiers for Constructors

  • Control who can instantiate a class
  • Private constructors are common in Singletons and utility classes
java
public class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton() {} // private constructor

    public static Singleton getInstance() { return instance; }
}

5. Access Modifiers in Inheritance

Rules

  1. Subclass cannot reduce visibility of inherited methods
  2. protected allows subclass access across packages
  3. default is package-restricted, even for subclasses
java
package package1;
public class Parent {
    protected void show() { System.out.println("Protected"); }
}

package package2;
import package1.Parent;

public class Child extends Parent {
    @Override
    public void show() { System.out.println("Overridden"); } // ✅ visibility not reduced
}

6. Access Modifiers and Interfaces

  • Fields: always public static final
  • Methods: public abstract by default
  • Java 8+: default and static methods in interfaces are allowed
java
public interface MyInterface {
    int CONST = 100; // public static final
    void abstractMethod(); // public abstract
    default void defaultMethod() { System.out.println("Default"); } // optional body
    static void staticMethod() { System.out.println("Static"); }
}

7. Combining Access Modifiers with Other Modifiers

CombinationAllowed?Notes
private staticCommon for utility constants
private finalImmutable private fields
protected abstractFor abstract base classes
private abstractIllegal; abstract methods must be accessible to subclasses
public static finalCommon for constants

8. Best Practices

  1. Minimize visibility: Keep members private unless necessary
  2. Use getters/setters: Controlled access for fields
  3. Encapsulation: Hide internal state
  4. Protected only for inheritance: Avoid unnecessary exposure
  5. Public only for API-facing methods
java
public class BankAccount {
    private double balance; // hidden

    public double getBalance() { return balance; } // controlled access
    public void deposit(double amount) { balance += amount; }
}

9. Common Mistakes

  • Overusing public → breaks encapsulation
  • Confusing default vs protected
  • Reducing visibility in overridden methods → compilation error
  • Forgetting package placement → default members inaccessible

10. Exercises

  1. Create a class Employee with:

    • Private field salary
    • Public getter/setter
    • Protected method showDetails()
  2. Create a subclass in another package and try to access all fields/methods

  3. Implement a Singleton utility class with a private constructor

  4. Create an interface with default and static methods, then implement it


11. Summary Table

ModifierClassPackageSubclassWorld
private
default
protected
public

This full tutorial now includes:

  • Definitions, rules, and examples
  • Classes, fields, methods, constructors
  • Inheritance rules, interfaces, and combinations
  • Best practices and mistakes
  • Exercises for hands-on learning

© 2023-2025 Maduranga Kannangara. Feel free to use or share this content. Attribution is appreciated but not required.