Java Finalize Method (Deprecated)

Naveen AnamaneniUpdated · 5 min read

Object has a method called finalize() that the garbage collector was supposed to call just before destroying an object, so the object could release files, sockets or other resources. It sounded useful, and old code and interview questions still mention it. In practice it was unreliable, slow and dangerous, so it was deprecated in Java 9 and is now marked for removal. This lesson explains why, and shows what to use instead.

The Warning You'll See

Fin.java
public class Fin {
    @Override
    protected void finalize() { System.out.println("cleanup"); }
}
Compiler output
Fin.java:3: warning: [removal] finalize() in Object has been deprecated and marked for removal
    protected void finalize() { System.out.println("cleanup"); }
                   ^
1 warning

It still compiles, but the compiler is telling you that a future Java version will remove it. Since Java 18 you can even switch finalization off completely with java --finalization=disabled, to test whether your program secretly depends on it.

Why It Never Worked Well

ProblemWhy it matters
No guarantee it runsThe GC may never collect the object before the program ends
No guarantee whenIt might run seconds or minutes later, so files and connections stay open
SlowObjects with finalizers need extra GC work and survive longer
Can resurrect objectsfinalize can store this somewhere, bringing a "dead" object back
Exceptions are ignoredAn exception thrown in finalize is silently swallowed
Security holesFinalizer attacks could use half-built objects

What to Use Instead

The right tool is to close resources yourself, at a known moment. Any class can opt in by implementing AutoCloseable, and a try-with-resources statement closes it automatically, even if an exception is thrown:

Receipts.java▶ Try it
public class Receipts {
    static class ReceiptPrinter implements AutoCloseable {
        private final String counter;
 
        ReceiptPrinter(String counter) {
            this.counter = counter;
            System.out.println("Printer opened at " + counter);
        }
 
        void print(String customer, long amount) {
            System.out.println("Receipt: " + customer + ", Rs. " + amount);
        }
 
        @Override
        public void close() {
            System.out.println("Printer closed at " + counter);
        }
    }
 
    public static void main(String[] args) {
        try (ReceiptPrinter p = new ReceiptPrinter("Counter 3")) {
            p.print("Advitha", 640);
            p.print("Navika", 1210);
        }
        System.out.println("Done");
    }
}
Output
Printer opened at Counter 3
Receipt: Advitha, Rs. 640
Receipt: Navika, Rs. 1210
Printer closed at Counter 3
Done

How it works

  1. ReceiptPrinter implements AutoCloseable, which has one method: close().
  2. try (ReceiptPrinter p = ...) declares the resource in parentheses. When the block ends, normally or through an exception, Java calls p.close() automatically.
  3. The cleanup happens at a known point, before "Done", which finalize could never promise.

Files, streams, database connections and sockets in the JDK all implement AutoCloseable, and the later lessons on exceptions and file I/O use them heavily.

Common Mistakes

Relying on finalize or the GC to close files. Close them explicitly with try-with-resources.

Calling System.gc() to "make finalize run". It's only a hint, and the timing is still unpredictable.

Answering "finalize is like a C++ destructor". Destructors run at a known time; finalize may never run.

Interview Corner

What is finalize() and why is it deprecated?

finalize() is a protected method of Object that the garbage collector could call before reclaiming an object, intended for releasing resources. It's deprecated, and marked for removal, because there's no guarantee it runs or when, it slows garbage collection, exceptions in it are ignored, it can resurrect objects, and it enabled security attacks. Resources should be released explicitly with try-with-resources, with Cleaner as an optional safety net.

What is the difference between final, finally and finalize?

final is a keyword that makes a variable unchangeable, a method non-overridable or a class non-extendable. finally is a block after try that always runs, used for cleanup. finalize() is a deprecated Object method that the garbage collector might call before reclaiming an object.

Practice

  1. Easy: Write a Session class that implements AutoCloseable, prints when it opens and closes, and use it with try-with-resources.
  2. Harder: Throw an exception inside the try block of Receipts after the first receipt, and catch it outside. Does close() still run? In which order are the lines printed?

Quick check: finalize()

4 questions
1What is the status of finalize() in Java 25?
2Is finalize() guaranteed to run?
3What closes a resource automatically at the end of a block?
4Which interface must a class implement to be used in try-with-resources?

Key Takeaways

Was this tutorial helpful?

Lesson 156 of 482