What are the access levels in Java, and what does each one actually let another class do?
There are four levels. Private members are visible only inside the declaring class. Package-private members are visible to every class in the same package and nowhere else, which is the default when you write no modifier. Protected members are visible in the same package and to subclasses in other packages. Public members are visible everywhere.
public class Main {
public static void main(String[] args) {
Account a = new Account("Ada");
System.out.println(a.owner());
System.out.println(a.balance());
a.deposit(50);
System.out.println(a.balance());
}
}
class Account {
private final String owner;
private double balance;
Account(String owner) { this.owner = owner; }
public String owner() { return owner; }
public double balance() { return balance; }
public void deposit(double amount) { balance += amount; }
}The account class shows the practical default. The owner and balance fields are private, so nothing outside the class can read or write them directly. The three public methods form the class's public contract: you can ask who the account belongs to, ask the balance, and deposit money. The output shows the balance moving from zero to fifty through that contract only.
The ordering of the levels is a widening scale, from most restricted to least. Each step out makes the member available in more places, and with it more coupling, because every new place that can see a member is a place that can depend on it.
The one that catches people out is protected. It sounds like a compromise between package access and public access, but it does something package access does not: it reaches across package boundaries into subclasses. That is a coupling to a family of classes that you do not control and cannot see all of, which is why exposing protected mutable state is generally treated as a mistake.