15. The final Keyword
final means different things depending on context: for variables it means assign-once; for methods it prevents overriding; for classes it prevents inheritance; for parameters it prevents reassignment inside the method.
Explanation
final variable: must be assigned exactly once; blank finals (fields declared final without an initialiser) must be set in every constructor. This applies to local variables, instance fields, and class (static) fields.
final method: cannot be overridden by a subclass. All private methods are implicitly final (they can't be overridden anyway, just hidden).
final class: cannot be subclassed at all. String, Integer, and all other wrapper classes are final. This enables optimisations and guarantees immutability invariants.
final parameter: the parameter variable cannot be reassigned inside the method body. It does not affect the caller (Java is pass-by-value). It's a compile-time guard against accidental shadowing and common in anonymous classes (where captured variables must be effectively final).
Example
public class FinalKeyword {
// final field โ must be set in constructor
private final String name;
private static final int MAX_SIZE = 100; // compile-time constant
FinalKeyword(String name) {
this.name = name; // blank final assigned in constructor
}
// final method โ cannot be overridden
public final String getName() { return name; }
// final class โ cannot be subclassed
static final class ImmutablePoint {
final int x, y;
ImmutablePoint(int x, int y) { this.x = x; this.y = y; }
}
// final parameter โ cannot reassign inside method
static int add(final int a, final int b) {
// a = 0; // compile error!
return a + b;
}
public static void main(String[] args) {
// final local variable
final String greeting = "Hello";
// greeting = "Hi"; // compile error!
// effectively final: captured by lambda without explicit final
String prefix = "Mr. "; // effectively final โ not reassigned
Runnable r = () -> System.out.println(prefix + "Smith");
r.run();
System.out.println("MAX_SIZE: " + MAX_SIZE);
System.out.println("add(3,4): " + add(3, 4));
ImmutablePoint p = new ImmutablePoint(1, 2);
System.out.println("Point: (" + p.x + ", " + p.y + ")");
}
}Sources
- https://docs.oracle.com/javase/tutorial/java/IandI/final.html โ Final classes and methods
- https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.3.1.2 โ JLS: final fields