Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Yes. In Java, an object whose finalizer runs can make itself reachable again—for example, by storing this in a static field. This is called object resurrection. It does not make finalization repeat: a Java virtual machine invokes a given object’s finalizer at most once. If the resurrected object later becomes unreachable again, that finalizer will not run a second time.

What is object resurrection in Java?

Object resurrection is when an object becomes reachable again after it has become eligible for finalization. Ordinarily, once no live thread can reach an object, the garbage collector may reclaim it. But if the object’s finalize() method runs, that method can publish a reference to the object and make it reachable again.

For example, an override might assign this to a static field:

static Object saved;

@Override
protected void finalize() {
    saved = this;
}

This illustrates the mechanism, not a recommended design. The Java SE 24 Object API permits a finalizer to make the object available to other threads, while specifying that the VM never invokes that object’s finalizer more than once: Oracle Java SE 24 Object API.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How can an object be eligible for finalization but still come back?

Java’s specification describes object lifecycle in terms of reachability and finalization state. An object may cease to be reachable from live threads and become eligible for finalization, but its finalizer can still execute code before its storage is reclaimed. If that code creates a new reference from a reachable location, such as a static field, the object is reachable again.

Finalization applies only after the Object constructor has completed successfully. Java SE 26 distinguishes reachable, finalizer-reachable, and unreachable objects, along with unfinalized, finalizable, and finalized states. See Chapter 12 of the Java Language Specification, Java SE 26 Edition.

What happens when a resurrected object becomes unreachable again?

If the resurrected object later has no live references, it can again become eligible for garbage collection. Its finalizer will not be invoked again: the VM’s at-most-once rule applies to each object, not to each transition to unreachability. The object may then be reclaimed without another automatic finalizer call.

Why is finalize() not reliable cleanup?

Finalization cannot provide dependable resource-release timing or ordering. The Java Language Specification leaves invocation timing unspecified apart from requiring that finalization precede reuse of the object’s storage. The Java SE 24 API warns that a finalizer may be delayed indefinitely when finalization is enabled, and it is never called when finalization is disabled or removed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • No promptness guarantee: becoming unreachable does not mean cleanup happens promptly. Calling System.gc() does not force finalization.
  • No ordering guarantee: finalizers may run concurrently and in an unspecified order; the language does not specify which thread invokes a particular finalizer.
  • Exceptions do not recover cleanup: an exception escaping a finalizer is ignored and terminates that object’s finalization.
  • Resurrection complicates lifecycle: code can make the object available again, but there is no second automatic finalizer call when it later becomes unreachable.

These rules make finalization unsuitable for correctness-critical cleanup, resource management, or coordination between objects.

What should you use instead?

Choose a cleanup mechanism based on whether your code controls the resource’s lifetime or needs a fallback associated with garbage collection.

Use close() and try-with-resources for controlled lifetimes

When your application knows when a resource is no longer needed, implement AutoCloseable and close it explicitly. Try-with-resources ensures that close() is called when the block exits, including when an exception occurs:

try (var input = new FileInputStream(path)) {
    // Read from input.
}

This is the appropriate choice for resources such as files, sockets, or other resources whose release should happen at a defined point in program flow.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Cleaner or PhantomReference only for reachability-associated cleanup

When explicit cleanup is not sufficient and cleanup needs to be associated with an object becoming unreachable, Java provides Cleaner and PhantomReference. They are alternatives to finalization, not guarantees of prompt execution; do not rely on them for immediate release. Oracle documents both APIs in the Java SE 24 Cleaner API and Java SE 24 PhantomReference API.

The Object API also points to Reference.reachabilityFence for cases where an object must remain reachable while its embedded resources are in use.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

What is the current status of Java finalization?

In the Java SE 24 API, Object.finalize() is deprecated and marked for removal. The Java SE 26 Language Specification says implementations may disable finalization in anticipation of its removal in a future platform release. That does not mean finalization has already been removed from every Java runtime; check the documentation and configuration for the runtime you use.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.