What does the `final` keyword do when applied to a class versus a method in Java?
answer
- final class = no subclass (e.g. String)
- final method = no override, but class still extensible
- compile-time error, enforced by javac
- class lock is strongest; method lock is targeted
- separate meaning from final variable/field
basics
~20 sA final class can't be extended (no subclasses). A final method can't be overridden by a subclass, though the class itself can still be subclassed. Both lock down a piece of behavior so others can't change it.
solid answer
~40 s`final` on a class means it cannot be subclassed at all — `class Sub extends FinalClass` is a compile error. `String`, `Integer`, and the other wrapper types are classic examples. `final` on a method means subclasses cannot override that specific method, but they can still extend the class and override its non-final methods. So a final class is the stronger lock (no inheritance whatsoever), while a final method is a targeted lock on one piece of behavior within an otherwise extensible class. Both are compile-time enforced. The keyword expresses design intent — "I did not design this to be changed via inheritance" — and is checked by `javac`, not at runtime. Note `final` also applies to variables/fields (preventing reassignment), which is a separate, unrelated meaning of the same keyword.
code
java · 16 linespublic final class Money { // no subclass allowed
private final long cents; // (different 'final': no reassignment)
public Money(long cents) { this.cents = cents; }
}
public class Account {
public final void audit() {} // subclasses can't override this
public void describe() {} // subclasses MAY override this
}
// class Wallet extends Money {} // COMPILE ERROR: Money is final
class Savings extends Account {
// void audit() {} // COMPILE ERROR: audit() is final
@Override public void describe() {} // OK: describe() is not final
}go deeper
Knows final class = can't extend, final method = can't override, and that String is final. Can state it's a compile error.
Distinguishes the strength of the two locks, names JDK examples, and separates final-class/method from final-variable. Knows overloading still works.
Frames final as design intent enforced at compile time, connects final methods to template-method skeletons, and reasons about extensibility trade-offs.
Discusses sealing strategy across an API surface (final vs sealed vs package-private constructors), migration/back-compat implications of removing final, and JIT devirtualization benefits.
## Background: what inheritance and overriding mean In Java, **inheritance** lets one class (a *subclass*) be declared with `class B extends A {}`, so `B` automatically gains `A`'s fields and methods. **Overriding** is when the subclass supplies its own implementation of a method that the parent already defined — same name, same parameters — so calling that method on a `B` object runs `B`'s version even through a variable typed as `A`. This is the engine of *polymorphism* (one reference type, many runtime behaviors). The `final` keyword is a modifier that *removes* one of these capabilities, depending on where you put it. ## `final` on a class ```java public final class Money { ... } ``` This says: **no class may extend `Money`.** Any attempt — `class Wallet extends Money` — is a **compile-time error** ("cannot inherit from final Money"). There are no subclasses, ever. Real-world final classes in the JDK include `String`, `Integer`, `Long`, `Double` (all the wrapper types), `LocalDate`, and `Optional`. Because a final class can't be subclassed, none of its methods can be overridden either (there's no subclass to override them in). So `final class` is the *strongest* lock: it forbids inheritance entirely. ## `final` on a method ```java public class Account { public final void recordAudit() { ... } // cannot be overridden public void describe() { ... } // can be overridden } ``` This is a *narrower* lock. The class `Account` is still extensible — subclasses are allowed. But within any subclass, `recordAudit()` **cannot be overridden**; `class Savings extends Account { void recordAudit(){} }` is a compile error. Meanwhile `describe()`, which is *not* final, can be overridden freely. So a final method pins down one specific behavior while leaving the rest of the class open. ## Why these are different tools - **Final class** = "this whole type is sealed; extend it through composition, not inheritance." - **Final method** = "extend me if you like, but *this* method's contract is non-negotiable — you may not swap its behavior." A common pattern is a non-final class with a final *template method* that calls overridable *hook methods*: the skeleton (the final method) is fixed, the steps (non-final methods) are customizable. ## Enforcement and scope All of this is enforced by the compiler (`javac`) at compile time, not by the JVM at runtime — it's about what code is *legal to write*. `final` is also unrelated to `final` on a **variable or field**, which instead means "this reference/value cannot be reassigned after initialization." Same keyword, three distinct meanings: final class (no subclass), final method (no override), final variable (no reassignment). ## How to derive the answer Ask "what does inheritance let someone do?" → create subclasses and override methods. `final` selectively forbids those: on a class it forbids *subclassing* (and therefore all overriding); on a method it forbids *overriding that one method* while still allowing subclassing.
- Can you override a final method by overloading it (same name, different parameters)?Yes — overloading creates a different method signature, which `final` does not block. `final` only prevents *overriding* (same name and parameter list). A subclass may declare `recordAudit(String reason)` even if `recordAudit()` is final.
- If a class is final, is there any point in also marking its methods final?No — a final class can have no subclasses, so its methods can never be overridden regardless. Marking them final is redundant (and some style checkers flag it).
saying these in an interview costs you the question
- Saying a final method also prevents subclassing the class — it doesn't, only the method can't be overridden
- Confusing final (no override/subclass) with final on a variable (no reassignment)
- Claiming final is a runtime check — it's enforced at compile time
- Saying a final method can't be overloaded — it can; final blocks overriding, not overloading