Java modifiers answer two questions: who may access a member, and what special rules govern its behavior? Access modifiers control visibility. Non-access modifiers such as static, final and abstract describe ownership or implementation restrictions. Combining them correctly makes a class easier to use safely.
Review the related foundation lesson when you need a prerequisite. The complete programs below use Java 17-compatible syntax.
Access levels
public, protected, package access and private control where declarations can be accessed. Package access is expressed by omitting an access modifier.
public permits access wherever the declaring type is accessible; private restricts access to the enclosing top-level class and its nested members. With no access keyword, a member has package access. protected permits package access and subclass access, but cross-package subclass access has additional receiver restrictions. It is therefore inaccurate to describe protected as simply public to every subclass object everywhere.
Visibility for members and nested types
private members are for implementation details. protected also has subclass rules, especially across packages; it does not simply mean public to every subclass reference.
A top-level class can be public or have package access; private and protected apply to appropriate members or nested types, not ordinary top-level class declarations. A public type in a conventional source file must match that file's name. Start with the smallest useful visibility. Increasing visibility later is usually easier than withdrawing a public method that other code has already adopted.
Static and final behavior
static associates a member with its class. final prevents reassignment, overriding or inheritance depending on whether it applies to a variable, method or class.
static attaches a field or method to the class rather than an instance. final prevents reassignment of a variable, overriding of a method or extension of a class, depending on placement. A final list reference still permits changes to the list's contents. Constants commonly combine public, static and final, but the value should be immutable when callers are allowed to share it freely.
Abstract and specialized modifiers
abstract describes an incomplete class or method contract. Other modifiers such as synchronized, volatile and transient address particular runtime or storage concerns rather than visibility.
abstract says that a class cannot be instantiated directly or that a method requires an implementation in a concrete subclass. An abstract method cannot also be final, because one requires overriding while the other forbids it. synchronized coordinates monitor access; volatile supports visibility for a field but does not make a compound increment atomic. These words express different contracts, not interchangeable levels of safety.
Running the examples
Save name.java, compile it with javac --release 17 name.java, and run java name. Use each program's own public class name and filename.
How PermitModifiers produces its output
The example separates the shared immutable label from data owned by an individual object. Reading a static constant through the class name makes that ownership visible. The private field is accessed through a method rather than by an unrestricted external assignment, so later validation can remain inside the class.
How FinalListReference produces its output
final prevents names from being assigned another list after initialization. It does not freeze the ArrayList object that names refers to. Both add calls are legal and the list contains two entries. To forbid modifications to contents, use an unmodifiable collection or a genuinely immutable value design rather than relying on the reference modifier.
How LabelVisibility produces its output
UNIT is one class constant and is reached through LabelVisibility. count is an instance field with the numeric default zero. The public count method exposes a read operation without exposing a public writeable field. The nested code in the declaring class can access its private members, but unrelated callers should use the published method.
Read combined modifiers as separate promises
private final int id means access is restricted and the field may be assigned only through its permitted initialization. Neither word makes the field static. public static final String LABEL makes one published class value whose reference cannot be reassigned. The String itself is immutable, so that combination is suitable for a shared label. Contrast it with public static final ArrayList<String>: the reference is fixed but callers can still add elements. In practice, first choose visibility, then decide whether ownership is per object or per class, then choose reassignment restrictions. Reading each modifier independently prevents treating a long declaration as a single vague safety setting.
Java Summary
- public, protected, package access and private control where declarations can be accessed. Package access is expressed by omitting an access modifier.
- private members are for implementation details. protected also has subclass rules, especially across packages; it does not simply mean public to every subclass reference.
- static associates a member with its class. final prevents reassignment, overriding or inheritance depending on whether it applies to a variable, method or class.
- abstract describes an incomplete class or method contract. Other modifiers such as synchronized, volatile and transient address particular runtime or storage concerns rather than visibility.
- Continue with Java exercises, Java quizzes and the Java study roadmap.
Java Examples
Each example shows the code, the output it produces and what each part does.
Java Access and Non-Access Modifiers in a complete program
public class PermitModifiers {
static final class Permit {
static final String PREFIX = "Permit ";
private final String id;
Permit(String id) {
this.id=id;
}
String number() {
return id;
}
}
public static void main(String[] args) {
Permit permit = new Permit("P-42");
System.out.println(Permit.PREFIX + permit.number());
}
}Permit P-42Line-by-line explanation
- Line 14Evaluates
Permit.PREFIX + permit.number()and printsPermit P-42.
Final reference, mutable contents
public class FinalListReference {
public static void main(String[] args) {
final java.util.List<String> names = new java.util.ArrayList<>();
names.add("Mira");
names.add("Jon");
System.out.println(names.size());
}
}2Line-by-line explanation
- Line 6Evaluates
names.size()and prints2.
Shared constant and instance state
public class LabelVisibility {
public static final String UNIT = "pages";
private int count;
public int count() {
return count;
}
public static void main(String[] args) {
LabelVisibility item = new LabelVisibility();
System.out.println(LabelVisibility.UNIT);
System.out.println(item.count());
}
}pages
0Line-by-line explanation
- Line 9Evaluates
LabelVisibility.UNITand printspages. - Line 10Evaluates
item.count()and prints0.
Java FAQ
Does protected mean public?
No. It includes package access and restricted subclass access. In a different package, a subclass cannot use an arbitrary superclass instance to reach a protected instance member just because it extends that class. Check the receiver and the declaring package.
Can final make an object immutable?
A final field cannot be reassigned after its allowed initialization, but any referenced mutable object may still change. Immutability also requires controlling those objects, preventing unintended setters and avoiding leaked mutable internal references.
What is the default access level in Java?
If you write no access modifier, a class or member has package access, often called package-private: any class in the same package can use it, and classes in other packages can't. It sits between private and protected in how widely it can be reached.
In what order should modifiers be written?
Java accepts any order, but the convention follows the language specification: access first, then abstract, static, final, transient, volatile and synchronized. So write public static final int MAX = 10; and private static final, which is what code reviewers and tools expect to see.
Can a top-level class be private or protected?
No. A top-level class can only be public or have package access. private, protected and static are allowed on nested classes, where they control access from the enclosing class and the rest of the program.
Java Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Which modifier prevents a method from being overridden?
Why can final List values still accept add?
Java Quiz
2 questions to check what you learned.
Which access level is used when a member has no access keyword?
- Package access
- public
- protected
Can an ordinary top-level class be private?
- No, it can be public or have package access
- Yes, if main is public
- Yes, if it is final