← Back to Java

finalize() Method

JavaMidjava

The Question

What is the finalize() method in Java?

What a Strong Answer Covers

  • called by GC before object destruction
  • cleanup activity
  • protected method of Object
  • override to add cleanup logic
  • called only once
  • deprecated/unpredictable

Senior-Level Answer

`finalize()` is a method defined on `java.lang.Object` that the garbage collector is permitted to call on an object before reclaiming its memory, giving the object a chance to release native resources or perform cleanup. It was part of Java from version 1.0.

The mechanism works as follows: when the GC determines an object is unreachable, it places the object on a finalization queue. A dedicated finalizer thread dequeues and calls `finalize()` on each object. After finalization, the GC can reclaim the object's memory on the next cycle.

In practice, `finalize()` has severe problems that led to its deprecation in Java 9 and its removal/forRemoval marking in Java 18:

1. Unpredictability. There is no guarantee about when — or even whether — `finalize()` will be called. The JVM specification allows it to never run, including on normal JVM exit. 2. Performance impact. Objects with non-trivial finalizers require at minimum two GC cycles to collect, prolonging their lifetime and increasing memory pressure. 3. Resurrection risk. A finalizer can store `this` in a static field, resurrecting the object. This complicates GC logic significantly. 4. Exception swallowing. Any exception thrown from `finalize()` is silently ignored, making debugging difficult. 5. Security. Malicious finalizers in subclasses can exploit the finalization delay to access resources that should have been closed.

The correct alternatives are: - `try-with-resources` with `AutoCloseable` — deterministic, exception-safe cleanup via `close()`. - `java.lang.ref.Cleaner` (Java 9+) — a phased, safer alternative to finalization for native resource cleanup when `AutoCloseable` is impractical. - Explicit `close()` or `dispose()` patterns for long-lived resources.

For interviews: know what finalize does, why it is problematic, and what replaced it.

What Separates a 2/3 from a 3/3

2/3 — Passing but Incomplete

Explains that finalize() is called before GC cleanup and lists at least two of its reliability problems.

3/3 — Strong Answer

Also covers the two-GC-cycle collection cost, the Java 9 deprecation, and the correct modern alternatives (try-with-resources, Cleaner).

Common Mistakes

  • Claiming finalize() is guaranteed to run before an object is collected — the JVM may never call it.
  • Recommending finalize() for resource cleanup in new code — it has been deprecated since Java 9.
  • Not mentioning try-with-resources as the standard replacement for deterministic cleanup.

Follow-Up Questions

  • Why does a finalizable object require at least two GC cycles to be collected? — First cycle: GC detects unreachability and queues for finalization. Second cycle: after finalize() runs, GC collects the now-truly-unreachable object.
  • What is java.lang.ref.Cleaner and how does it improve on finalize()? — Cleaner uses phantom references and a dedicated thread; cleanup actions run outside the object's class hierarchy, preventing resurrection.
  • How does try-with-resources guarantee close() is called even if an exception is thrown inside the block? — The compiler generates a finally-like structure; if both the body and close() throw, the body exception is primary and close()'s is suppressed.

Related Questions

  • JVM vs JRE vs JDK
  • Java Platform Independence
  • How JVM Works
  • Main Features of Java
  • public static void main

Can You Explain This Cold?

Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.

Get Graded — Free Assessment
GrindQuestionsAITechnical interview assessment
TermsPrivacyAbout