Object Finalization in Java | Finalize, Example

Finalization in Java is an action that is automatically performed on an object before the memory occupied by the object is freed up by the garbage collector.

The block of code that contains the action to be performed is called finalizer in java. In Java, the finalizer is just opposite to the constructor.

A constructor performs initialization for an object, whereas the finalizer method performs finalization for the object. Garbage collection automatically cleans up the memory occupied by unused objects.

But when objects hold other kinds of resources such as opening files, closing files, network connection, etc, garbage collection does not free these resources for you.

In this case, we need to write a finalizer method for an object that performs such tasks as closing files, deleting temporary files, terminating network connection, etc.

Finalizer Method in Java


A finalizer is an instance method that is provided by Object class, which is the top of the Java platform’s class hierarchy and a superclass of all classes in java.

To add a finalizer to a class, we simply declare a finalize( ) method. Inside the finalize( ) method, we will write the finalization code for those actions that must be performed before an object is destroyed by the garbage collector.

The syntax to declare finalize() method of Object class is as follows:

protected void finalize() throws Throwable
{
    // finalization code here.
}

This method does not accept any arguments and returns no value. Here, the keyword protected is an access modifier that prevents access to finalize( ) by code defined outside its class.

There can be only one finalize() method per class. A finalizer can throw any kind of error or exception, but when a finalizer is automatically called by a garbage collector then any exception or error it throws is ignored.

Important points about finalizer


1. The main objective of finalization is to call finalize() method before the garbage collection frees up the memory occupied by an object.

2. The finalize() method of Object class can be called by garbage collector only once before object is garbage collected.

3. An object’s finalize() method cannot be called while it is reachable.

4. Since all Java classes extend the Object class, therefore, the finalize() method can be called on all Java objects.

5. Any class can override and implement its own version of the finalize() method to perform finalization necessary for objects of that type.

6. The finalize() method does not invoke when an object goes out of scope.

Example Program based on Java Finalization


Let’s take a simple example to demonstrate that the finalize() method is called before an object is garbage collected. We will use a method finalize() in the Finalizer class.

Program source code 1:

package garbageCollectorProgram;
public class Finalizer 
{
// Declaring an instance variable id that is used to identify the object.
      private int id;
// Constructor which takes the id as parameter.
    public Finalizer(int id)
    {
	  this.id = id;
     }
// This is the finalizer for objects. JVM will call this method, before the object is garbage collected.
    public void finalize()
    {
// Here, we will display a message indicating which object is being garbage collected. 
// Display message when id is a multiple of 50.
     if (id % 50 == 0) 
     {
	  System.out.println ("finalize() method called for " + id ) ;
     }
 }
public static void main(String[] args) 
{
// Create 1000 objects of the Finalizer class
    for(int i = 1; i <= 1000; i++)
    {
// Do not store reference to the new object
	new Finalizer(i);
   }
// Invoking the garbage collector.
   System.gc();
 }
}
Output:
         finalize() method called for 50
         finalize() method called for 300
         finalize() method called for 400
         finalize() method called for 450
         finalize() method called for 500

The finalize() method of Object class displays a message if the object being garbage collected has an id, which is a multiple of 50.

The main() method creates 1,000 objects of class Finalizer and calls gc() method of System class to invoke the garbage collector.

When the garbage collector determines that an object is unused (or unreachable), it marks that object for finalization and puts that object in a queue.

Suppose we want the JVM to finalize all objects that are pending for finalization. This can be done by calling runFinalization() method of the Runtime class, as follows below:

Runtime rt = Runtime.getRuntime();
  rt.runFinalization();

The System class has a convenience runFinalization() method, which is similar to calling the runFinalization() method of the Runtime class. It can be called like this:

System.runFinalization();

Calling of the runFinalization() method is only a request to the JVM to call the finalize() method for all objects that are pending for finalization.

Finally or Finalize which is better to use?


There is no guarantee when the finalize() method for an unreachable object will be called or it will be called definitely.

So, what is the good thing about the finalize() method?

The main objective of a garbage collector in Java is to release programmers from the burden of cleaning up the memory of unused objects to avoid the problem of memory leaks and dangling references.

Its secondary task is to run the finalization on the objects without a guaranty.

As a programmer, we should not depend much on the finalization process of garbage collection. We should write the code inside finalize() method with care.

If you need to free up resources for sure, you should use a try-finally block, as follows:

try {
    // Code for getting your resources and work with them.
}
finally {
    // Code for releasing your resources.
}

We can get resources and work with them in a try block and release them in the associated finally block. A finally block is guaranteed to be executed after a try block is executed.

This way, we can sure that resources used in the program are always freed once we are worked with them.

However, it may not always be possible due to the performance issues, to free resources immediately after working with them.

For instance, we may not want to open a network connection every time we need it. We generally open a network connection once, use it, and close it when we no longer need it.

Sometimes we may not know the exact time in a program from where we will not require that network connection. In such situations, we can write the code inside the finalize() method as a backup to free the resources if they have not been released yet.


Hope that this tutorial has covered almost all the important points related to object finalization in java with example program. I hope that you will have understood the basic concepts of Java object finalization.
Thanks for reading!!!
Next ⇒ Generics in Java⇐ Prev Next ⇒