Static Variables in Java β Class-level State
A static variable (class variable) belongs to the class itself β one copy, shared by every instance and accessible without any instance. Use it for constants and immutable shared data. Mutable static state is almost always a mistake.
Declaration
public class Counter {
private static int total; // ONE slot for the whole class
private int mine; // one per instance
public void increment() {
total++;
mine++;
}
}
Constants β static final
public class Config {
public static final int MAX_RETRY = 3;
public static final String BASE_URL = "https://api.example.com";
public static final Duration TIMEOUT = Duration.ofSeconds(30);
}
The canonical form for a constant. Conventional naming: UPPER_SNAKE_CASE.
Static initialiser block
public class Country {
private static final Map<String, String> CODES;
static {
var m = new HashMap<String, String>();
m.put("fr", "France");
m.put("de", "Germany");
CODES = Map.copyOf(m);
}
}
Runs once, at class loading. If it throws, the class can't be used β you'll see ExceptionInInitializerError.
Default values
Same as instance fields: 0, false, null. Like instance fields, static fields don't need explicit initialisation.
Access
Math.PI; // β
ClassName.field β preferred
Config.MAX_RETRY;
Counter c = new Counter();
c.total; // β
compiles, bad style β obscures staticness
The problem with mutable static state
- Thread-safety by default is broken β every thread sees the same field without coordination.
- Hard to test β test pollution when one test changes the state.
- Hidden dependencies β a method that reads
SomeClass.configpretends to be pure but depends on a global.
Prefer dependency injection for shared state. Use static only for constants and pure functions.
Memory and class unloading
Static fields live as long as the class loader that loaded them. In long-running applications (app servers, web frameworks with hot reload), a static field holding a big structure can leak memory if the class loader can't be released.
Common mistakes
- Mutable static state across threads β race conditions.
- Static collections as caches without eviction β silent memory leak.
- Forgetting
finalon constants βpublic static int MAX = 100;is a global mutable. Addfinal.
Related
Pillar: Variables in Java. See also static keyword, final variables.