final (keyword)

final has three distinct meanings in Java depending on what it modifies: a variable that cannot be reassigned, a method that cannot be overridden, or a class that cannot be subclassed.

final variable

final int MAX = 100;
// MAX = 200;  // compile error

final List<String> list = new ArrayList<>();
list.add("hi");  // the reference is final, but the list contents are mutable

final on a reference variable means the reference cannot be reassigned — but the object it points to can still be mutated. For full immutability, the object itself must be immutable.

final method

public class Parent {
    public final void fixed() { /* cannot be overridden */ }
}
// In a subclass, attempting to override fixed() is a compile error.

final class

public final class Money {
    // cannot be extended
}

String, Integer, and all wrapper classes are final — their contracts cannot be changed by subclassing.

Effectively final

A local variable that is never reassigned is "effectively final" even without the keyword. Lambdas and anonymous classes can capture effectively final variables:

int multiplier = 10;              // effectively final (not reassigned)
Function<Integer, Integer> f = n -> n * multiplier;

Best practice

Make all fields final by default — reach for mutability only when needed. It is one of the easiest ways to make code simpler to reason about.