Codectionary / Developer documentation / Java

Access Modifiers

Access modifiers control the visibility of classes, fields, and methods from other parts of a program. Java has four levels: public (accessible from anywhere), protected (accessible within the same package and by subclasses), default/package-private (accessible only within the same package, used when no modifier is written), and private (accessible only within the declaring class itself).

Syntax

public | protected | (default) | private

Examples

The Four Access Levels

Demonstrating each modifier on fields within a class.

public class AccessDemo {
    public int publicField = 1;        // accessible from anywhere
    protected int protectedField = 2;   // accessible in package + subclasses
    int defaultField = 3;                // accessible only within the same package
    private int privateField = 4;        // accessible only within this class

    private void showAll() {
        // all four are accessible from inside the class itself
        System.out.println(publicField + protectedField + defaultField + privateField);
    }
}

Private Fields with Public Accessors

The standard encapsulation pattern: hide data, expose controlled access through methods.

public class Account {
    private double balance;  // hidden from outside access

    public Account(double initialBalance) {
        this.balance = initialBalance;
    }

    public double getBalance() {  // controlled read access
        return balance;
    }

    public void deposit(double amount) {  // controlled write access, with validation
        if (amount > 0) {
            balance += amount;
        }
    }
}

Account acc = new Account(100);
// acc.balance = -500;  // Error - balance is private, can't be accessed directly
acc.deposit(50);
System.out.println(acc.getBalance());  // 150.0

protected and Inheritance

protected members are accessible to subclasses even if they're in a different package.

public class Vehicle {
    protected int speed;

    protected void accelerate() {
        speed += 10;
    }
}

public class Car extends Vehicle {
    public void drive() {
        accelerate();  // accessible because Car extends Vehicle
        System.out.println("Speed: " + speed);
    }
}

Car car = new Car();
car.drive();  // Speed: 10

Best practices

  • Default to private for fields, exposing access only through public getter/setter methods when genuinely needed (encapsulation)
  • Use protected specifically when subclasses need access, and public only for the intentional external API of a class
  • Avoid the temptation to make everything public "just in case" - it removes the safety encapsulation is meant to provide
  • Keep helper methods that support a public method private, so implementation details stay hidden and changeable

Runtime & versions

Java Virtual Machine. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

Java Language Specification

Specifications & further reading