Access Modifiers
Java modifiers: public / private / protected / package-private, static, final, abstract, synchronized, volatile. The keywords that shape access + behaviour.
Java — modifiers
EXAMPLE
// ===== Access modifiers =====
public class User { ... } // accessible everywhere
class Helper { ... } // package-private (default; same package only)
public class Foo {
public int a; // anywhere
protected int b; // subclasses + same package
int c; // package-private (default)
private int d; // this class only
}
// Best practice: most fields private; expose via methods.
// ===== static =====
// Belongs to the CLASS, not an instance.
public class MathUtil {
public static final double PI = 3.14159;
public static int add(int a, int b) { return a + b; }
}
MathUtil.add(2, 3);
// Static fields are shared across all instances (also across threads — beware races).
// ===== final =====
// On classes: cannot be subclassed
public final class Money { ... }
// On methods: cannot be overridden
public final void critical() { ... }
// On fields: assigned once
public final int id = 42;
// On parameters: cannot be reassigned in method body
public void demo(final String name) { ... }
// On locals: same; aids readability
// ===== abstract =====
public abstract class Shape {
public abstract double area(); // no body; subclass must implement
public void describe() { System.out.println(area()); }
}
class Circle extends Shape {
double r;
public double area() { return Math.PI * r * r; }
}
// You CANNOT instantiate an abstract class. It must be subclassed.
// ===== synchronized =====
// Mutual exclusion via the intrinsic lock of an object.
public synchronized void increment() {
count++;
}
// Same as: synchronized(this) { count++; }
// Static synchronized uses the Class object's lock.
// Prefer java.util.concurrent (Lock, ReentrantLock, AtomicInteger) for new code.
// ===== volatile =====
// Ensures visibility across threads (no caching) but NOT atomicity for compound ops.
private volatile boolean running = true;
// For atomic counters, use AtomicInteger / AtomicLong, not volatile int + ++.
// ===== transient =====
// Excluded from default Java serialisation.
public class Session implements Serializable {
private String userId;
private transient String temporaryToken; // not serialised
}
// ===== native =====
// Method implemented in another language (C via JNI). Rare in app code.
public native int sumNative(int a, int b);
// ===== Modifier interactions =====
// public + abstract: an API contract; subclasses fill in
// final + private: redundant (private methods are inherently final)
// static + final: a compile-time constant pattern (Java's idea of const)
// protected + final: rare; a method whose implementation must not be overridden but is visible to subclasses for calling
// ===== sealed (Java 17+) =====
// Restrict who can extend / implement:
public sealed class Shape permits Circle, Square, Triangle { ... }
public final class Circle extends Shape { ... }
public non-sealed class Square extends Shape { ... } // sub-subclasses allowed
public final class Triangle extends Shape { ... }
// ===== Patterns to internalise =====
// - private fields by default; public methods only when needed
// - final on locals + params to document intent
// - static final UPPER_SNAKE for constants (only legitimate UPPER_SNAKE use)
// - Avoid synchronized in new code; reach for java.util.concurrent
// ===== Pitfalls =====
// - public mutable fields -> consumers depend on internals
// - volatile int + ++ -> NOT atomic; race condition
// - Inheriting from a non-final class without knowing if it was designed for inheritance
// - synchronized methods that hold the lock during I/O -> bottleneck
Why it matters
Modifiers shape access and behaviour: access (public/private/protected/default), static for class-level, final for immutable bindings, abstract for contracts, synchronized + volatile for concurrency (use java.util.concurrent first). sealed locks down inheritance in Java 17+. Default to the most restrictive that still works.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
public // anywhere
protected // package + subclasses
// (default) package-private
private // declaring class only
Try it Yourself »
Discussion
Loading…