Difference between Static and final?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Java, static and final are both modifiers, but they answer completely different questions. static is about class-level ownership and lifecycle. final is about things that should not be reassigned, overridden, or extended. Confusing them leads to APIs that are harder to reason about and harder to test.
static Means the Member Belongs to the Class
A static field or method is attached to the class itself rather than to any particular instance. Every object shares the same static field, and static methods can be called without creating an instance.
Here total is shared state. That is the core meaning of static: one class-level value, not one value per object.
final Means the Contract Cannot Change in That Way
final depends on where you use it:
- A
finalvariable cannot be reassigned. - A
finalmethod cannot be overridden. - A
finalclass cannot be subclassed.
This code says two things: Config is not meant to be extended, and timeoutMs cannot point to a different integer value after construction.
static final Is Common for Constants
Because the two modifiers solve different problems, they are often combined. A constant that is shared by the entire class is naturally static final.
This is a class-scoped constant. It does not vary by instance, and it should not be reassigned.
final Does Not Automatically Mean Deep Immutability
One of the most common misconceptions is that final makes an object fully immutable. It does not. A final reference cannot be changed to point somewhere else, but the object it points to may still be mutable.
The names variable is final, but the list contents still change. If deep immutability matters, you need immutable objects or defensive copying, not just the final keyword.
static Does Not Mean Thread-Safe
Another common mistake is assuming class-level state is somehow safer or more controlled. Shared mutable static fields can be some of the hardest state to manage because every instance and every thread can reach them.
If shared state must exist, it still needs the right concurrency strategy. static changes ownership, not synchronization.
Use the Modifier That Matches the Design Goal
Use static when the value or behavior is genuinely class-wide, such as utility functions, constants, or carefully managed shared infrastructure. Use final when you need a stronger contract around reassignment or inheritance. If you are reaching for static just to avoid dependency injection, that is often a design smell. If you are reaching for final without being clear about whether you want shallow or deep immutability, the code may still be misleading.
In code review, the best question is not "can this compile with static or final." It is "what guarantee are we trying to express."
Common Pitfalls
The usual mistakes are treating static state as if it were automatically safe, treating final references as if they implied deep immutability, and adding final or static by habit instead of design intent. Teams also create hard-to-test global state with mutable static fields when instance-based dependencies would have been clearer.
Summary
- '
staticmeans class-level ownership and shared lifecycle.' - '
finalmeans no reassignment, no override, or no subclassing, depending on location.' - '
static finalis the standard combination for shared constants.' - '
finaldoes not guarantee deep immutability.' - '
staticdoes not provide thread safety by itself.'

