What does the final keyword mean when applied to a local variable, and what happens if you try to reassign it?
answer
- final = assign once
- compile-time error on reassignment
- blank final + definite assignment
- not a compile-time constant
- freezes the binding, not the object
basics
~10 sfinal means the variable can be assigned a value only once. After that first assignment you cannot change it. Trying to reassign it is a compile error, so the program will not even build.
solid answer
~40 sApplying final to a local variable makes it assign-once: you may set its value a single time, after which any reassignment is a compile-time error. You can declare it and assign later (a 'blank final'), but the compiler must be certain it is assigned exactly once before use on every code path. final does not require the initial value to be a compile-time constant; it can be any runtime expression. It only restricts the variable binding (the slot), not the object the variable may point to. The main benefits are clearer intent (this value will not change), help catching accidental reassignment bugs, and it is required for a local variable to be captured by a lambda or anonymous class (it must be final or effectively final).
code
java · 10 linesfinal int max = 100;
// max = 200; // does not compile
final int parsed; // blank final
if (args.length > 0) {
parsed = Integer.parseInt(args[0]);
} else {
parsed = 0;
}
System.out.println(max + parsed);go deeper
Knows final means a variable can be assigned only once and reassignment fails to compile.
Explains blank finals, definite-assignment checking, and that final freezes the binding not the object.
Connects final to effectively-final lambda capture, notes it is not a compile-time constant, and uses it deliberately for clarity.
Discusses team conventions around final usage, readability vs. noise trade-offs, and how final interacts with the Java Memory Model and lambda capture semantics.
## What 'variable' and 'final' mean here A **variable** in Java is a named storage slot that holds a value. For a *local variable* (one declared inside a method) the slot lives on the method's stack frame. **Assigning** to a variable means putting a value into that slot. The **`final` keyword** placed before a variable declaration makes the slot **assign-once**: once a value has been written into it, the compiler forbids writing again. Example: ```java final int x = 10; x = 20; // COMPILE ERROR: cannot assign a value to final variable x ``` This error happens at **compile time** (when `javac` builds the code), not at runtime. The program simply will not compile. ## Blank finals and definite assignment You do **not** have to assign on the same line as the declaration. This is legal: ```java final int y; if (cond) { y = 1; } else { y = 2; } use(y); ``` This is called a **blank final** — declared `final` but not yet initialized. The compiler runs a check called **definite assignment**: it proves the variable is assigned **exactly once** on every possible path before it is read. If some path leaves it unassigned, or some path could assign it a second time, the code is rejected. ## final does not mean compile-time constant A common confusion: `final` does **not** require the value to be known at compile time. This is perfectly valid: ```java final int now = computeSomething(); // runtime value, still final ``` The value is computed while the program runs; `final` only means it is set once and never reassigned. ## final restricts the binding, not the object For reference variables, `final` freezes which object the variable points to, **not** the object's internal state: ```java final List<String> list = new ArrayList<>(); list.add("hi"); // OK — mutating the object is allowed list = new ArrayList<>(); // COMPILE ERROR — repointing is not allowed ``` ## Why use it 1. **Intent** — readers see the value will not change. 2. **Bug prevention** — the compiler catches accidental reassignment. 3. **Lambdas / anonymous classes** — a local variable captured by a lambda or anonymous inner class must be `final` or **effectively final** (never reassigned after initialization). Declaring it `final` makes that requirement explicit.
- Does final require the value to be known at compile time?No. final only means assign-once. The value can be any runtime expression, e.g. final int n = readFromFile();. Compile-time-constant behavior needs static final with a constant expression.
- What is a blank final?A variable declared final without an initializer on the same line; it must then be definitely assigned exactly once before use on every code path, or the code will not compile.
A final variable is like writing a value in permanent ink on a luggage tag: you can fill the tag once, but you cannot erase and rewrite it. The bag inside (the object) can still be repacked.
saying these in an interview costs you the question
- Thinking reassigning a final fails at runtime — it is a compile-time error.
- Believing final means the value must be a constant known at compile time.
- Claiming final on a reference makes the referenced object immutable.
- Assuming you must always initialize a final on its declaration line.