final classes & methods in Java
Preventing extension and overriding.
class EvilString extends String and make every password check return true? Java's designers made very sure you can't.final class: end of the line
A **final class cannot be extended** — any class Sub extends FinalClass is a compile error. String, Integer and Math are all final classes.
public final class String { ... }final method: no overrides
A **final method is inherited but cannot be overridden**. Every subclass uses exactly that implementation. Overloads — same name, different parameters — are still allowed, because they're different methods.
class A {
final void f() { }
}
class B extends A {
void f(int x) { } // OK: overload
}Breaking into the vault
What happens?
final class Vault { }
class Thief extends Vault { }
void main() { System.out.println("in!"); }in!Compile errorThrows IllegalAccessError
Show the answer
Compile error. Vault is final, so the compiler refuses to let Thief extend it. Nothing runs at all.
Locking one step
Why make just one method final in a class open for extension? To protect a critical algorithm: a final play() fixes the order of steps, while subclasses customize the individual, non-final steps. That's the *template method* pattern.
abstract class Game {
final void play() {
start(); turn(); end();
}
abstract void turn();
}Don't assume
Not every JDK class is final: **ArrayList isn't** — you can extend it (though composition is usually better). And final on a private or static method adds nothing for overriding: those can't be overridden anyway.
In real projects
String being final is a security feature: nobody can sneak in a mutable "String" subclass that changes after a permission check. Library authors follow the rule "design for inheritance or prohibit it" — and final is how you prohibit it.
Key takeaways
- final class: no subclasses
- final method: no overrides (overloads are still fine)
- private and static methods can't be overridden anyway
- Common in immutable and security-sensitive types
Kotlin made this the default: classes and methods there are final unless you mark them open.
Practice questions
What does this print?
final class Base { }
class Sub extends Base { }
void main() { System.out.println("ok"); }- ok
- Compile error
- Throws IllegalAccessError
Check your answer
Compile error. Base is final, so the compiler refuses to let Sub extend it.
What does this print?
class A { final void f() { } }
class B extends A {
void f() { }
}
void main() { System.out.println("ok"); }- ok
- Compile error
- Prints ok; B.f() silently replaces A.f()
Check your answer
Compile error. f() is final in A, so B may not override it.