Java
Programming
Software Development
Object-Oriented Programming
Memory Management

When is the finalize() method called in Java?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

The finalize() method in Java is part of the java.lang.Object class, from which every class in Java implicitly inherits. This method is called by the garbage collector on an object when the garbage collection determines that there are no more references to the object. Essentially, it gives an object one last chance to perform any cleanup before the object gets removed from the memory.

Understanding finalize()

The finalize() method is intended to be used to release system resources or to perform other cleanup when an object is being reclaimed by the garbage collector. However, it's important to note that the timing of when finalize() is executed is uncertain. The garbage collector runs on its own schedule, and there’s no guarantee it’ll run immediately after an object becomes unreachable. Therefore, relying on this method for any critical operation is generally discouraged.

Furthermore, from JDK 9 onward, finalize() has been deprecated due to its unpredictable nature and potential to create more problems than it solves – such as performance issues and difficulties in debugging.

When is finalize() called?

The finalize() method is called by the garbage collector when it determines that there are no longer any means by which an object can be accessed by any thread that is still alive. However, this could occur at an unpredictable time after an object becomes eligible for garbage collection. Also, there’s no assurance that finalize() will be called at all before the Java virtual machine exits. This unreliability is one reason why reliance on finalize() for releasing resources or other critical operations is strongly discouraged.

How to use finalize()

Despite its downsides and deprecation, understanding the use of finalize() can be beneficial, particularly when dealing with legacy Java code. Here's a simple example demonstrating the use of finalize():

java
1public class CleanupExample {
2    
3    @Override
4    protected void finalize() throws Throwable {
5        try {
6            // clean up non-Java resources like file handles, sockets, etc
7            System.out.println("Cleanup executed before object is removed");
8        } finally {
9            super.finalize();
10        }
11    }
12    
13    public static void main(String[] args) {
14        CleanupExample example = new CleanupExample();
15        example = null;
16        
17        // Requesting JVM to run Garbage Collector
18        System.gc();
19        System.runFinalization();
20    }
21}

In this example, we override the finalize() method. Inside the method, a cleanup activity is performed (just a print statement in this case). The call to System.gc() and System.runFinalization() in the main method is a way to request, but not guarantee, that the JVM performs garbage collection and finalization.

Better alternatives to finalize()

Since the use of finalize() is discouraged and unpredictable, Java offers better alternatives to manage resources cleanly:

  • Try-with-resources: Introduced in Java 7, this construct ensures that each resource is closed at the end of the statement. Each resource must implement the AutoCloseable or Closeable interface.
  • Cleaner and PhantomReference: Java 9 introduced the java.lang.ref.Cleaner class that provides a more flexible and efficient way to release resources than finalization.

Summary Table

Featurefinalize()Alternatives (Try-with-resources, Cleaner)
ReliabilityUnpredictablePredictable and reliable
Java VersionSince Java 1Try-with-resources since Java 7, Cleaner since Java 9
Usage RecommendationsDiscouraged, deprecated since JDK 9Strongly recommended for resource management

Conclusion

While finalize() offers a way to perform cleanup before object disposal, its unpredictability and deprecation status make it an unreliable choice for any critical resource management. Alternative methods such as using try-with-resources or Cleaner provide more robust and predictable resource management solutions. Therefore, adapting to newer and more efficient methods is advisable for maintaining and writing robust Java code.


Course illustration
Course illustration

All Rights Reserved.