Skip to content

Access Specifiers in Java

Access specifiers (or access modifiers) in Java determine the visibility or accessibility of classes, methods, variables, and constructors. They help control how and where these members can be accessed within and across different classes or packages.


Types of Access Specifiers

Java has four main access specifiers:

ModifierClassPackageSubclass (Different Package)World (Everywhere)
publicYesYesYesYes
protectedYesYesYesNo
No Modifier (Default)YesYesNoNo
privateYesNoNoNo

1. public Access Specifier

  • Members declared as public are accessible everywhere in the application.
  • Suitable for methods, variables, or classes that need to be universally accessible.

Example

public class PublicExample {

    public void showMessage() {

        System.out.println(“This is a public method.”);

    }

}

// Accessible from another class

public class Main {

    public static void main(String[] args) {

        PublicExample obj = new PublicExample();

        obj.showMessage(); // Works fine

    }

}


2. protected Access Specifier

  • Members declared as protected are accessible:
    • Within the same package.
    • In subclasses, even if they are in different packages.

Example

// Package: mypackage

package mypackage;

public class ProtectedExample {

    protected void showMessage() {

        System.out.println(“This is a protected method.”);

    }

}

// Another class in the same package

package mypackage;

public class Main {

    public static void main(String[] args) {

        ProtectedExample obj = new ProtectedExample();

        obj.showMessage(); // Works fine

    }

}

// Subclass in a different package

package otherpackage;

import mypackage.ProtectedExample;

public class SubClass extends ProtectedExample {

    public static void main(String[] args) {

        SubClass obj = new SubClass();

        obj.showMessage(); // Works fine

    }

}


3. Default (No Modifier)

  • If no access specifier is provided, the default access level is used.
  • Members are accessible only within the same package.
  • Often used when access should be restricted to a specific package.

Example

// Default access

class DefaultExample {

    void showMessage() {

        System.out.println(“This is a default method.”);

    }

}

// Accessible in the same package

class Main {

    public static void main(String[] args) {

        DefaultExample obj = new DefaultExample();

        obj.showMessage(); // Works fine

    }

}

  • Not Accessible in a Different Package:

import mypackage.DefaultExample; // Compilation error


4. private Access Specifier

  • Members declared as private are accessible only within the class in which they are defined.
  • Used for encapsulation, to restrict access to class members.

Example

public class PrivateExample {

    private void showMessage() {

        System.out.println(“This is a private method.”);

    }

    public void accessPrivateMethod() {

        showMessage(); // Accessible within the same class

    }

}

public class Main {

    public static void main(String[] args) {

        PrivateExample obj = new PrivateExample();

        // obj.showMessage(); // Compilation error

        obj.accessPrivateMethod(); // Works fine

    }

}


Encapsulation with Access Specifiers

Encapsulation is often achieved by making fields private and providing public getter and setter methods for controlled access.

Example

public class EncapsulationExample {

    private String name;

    // Getter

    public String getName() {

        return name;

    }

    // Setter

    public void setName(String name) {

        this.name = name;

    }

}

public class Main {

    public static void main(String[] args) {

        EncapsulationExample obj = new EncapsulationExample();

        obj.setName(“John”);

        System.out.println(obj.getName()); // Outputs: John

    }

}


Use Cases of Access Specifiers

Access SpecifierUse Case
publicUse for methods or variables that should be universally accessible (e.g., API endpoints).
protectedUse for methods or variables that should be available to subclasses but not the entire app.
DefaultUse when members should be accessible only within the same package.
privateUse to restrict access to the implementation details of a class.

Best Practices

  1. Default to Private:
    1. Start with private for fields and methods unless wider access is required.
  2. Minimize public Usage:
    1. Only use public when necessary for external access.
  3. Use protected for Inheritance:
    1. Make members protected if they are designed for subclass extension.
  4. Avoid Package Dependency:
    1. Don’t rely heavily on default access unless you have strict package boundaries.

By properly using access specifiers, you can enhance encapsulation, maintainability, and security in your Java applications.