JavaThe final Keyword

The final Keyword

final means “this cannot change again,” but exactly what it locks down depends on where you put it — a variable, a method, or a class. All three uses share the same spirit (immutability, non-overridability, non-extensibility) but apply to completely different things.

Applied to

Effect

Variable

Cannot be reassigned once given an initial value

Method

Cannot be overridden by any subclass

Class

Cannot be extended/subclassed at all

final variable

A final local variable, field, or parameter can be assigned exactly once. After that, any attempt to reassign it is a compile-time error.

final variables

Java
final double PI_APPROX = 3.14159;
PI_APPROX = 3.0; // error: cannot assign a value to final variable 'PI_APPROX'
Note
`final` fields combined with `static` are the standard way to define class-wide constants (`static final int MAX_USERS = 100;`) — see the dedicated **Constants (final)** page for the full pattern, including why constants are conventionally named in `ALL_CAPS`.
final method

A final method can be inherited by subclasses, but it cannot be overridden — a subclass is not allowed to provide its own version. This is useful when a method implements logic that must behave identically for every subclass, no exceptions.

This does not compile

Java
class Account {
    final double calculateInterest(double balance) {
        return balance * 0.01;
    }
}

class SavingsAccount extends Account {
    @Override
    double calculateInterest(double balance) { // error: cannot override
        return balance * 0.05;                 // final method
    }
}
final class

A final class cannot be extended at all — no class is permitted to subclass it, under any circumstances. The single most famous example in the entire JDK is String itself, which is declared final.

This does not compile

Java
class MyString extends String { // error: cannot inherit from final 'String'
}

String being final is a deliberate design decision, and it's part of the reason Strings can be trusted as immutable everywhere in the JDK. If String could be subclassed, some other code could override its methods to behave unexpectedly — for example, a malicious subclass could make equals() lie, or make length() return something inconsistent with the actual character data — quietly breaking any code (including core parts of the JDK, like security checks and hash-based collections) that assumes a String behaves the way String is documented to behave.

Warning
`final` on a class prevents inheritance, but it says nothing about the mutability of that class's fields on its own — you still need to make fields `private final` yourself for true object immutability. `String` combines both: it is a `final` class *and* every field inside it is effectively immutable once constructed.
  • final variable — assigned once, never reassigned.

  • final method — inherited, but never overridden by a subclass.

  • final class — cannot be extended by any subclass at all.