finalize() Method in Java

Learn via video course
FREE
View all courses
Java Course - Mastering the Fundamentals
Java Course - Mastering the Fundamentals
by Tarun Luthra
1000
5
Start Learning
Java Course - Mastering the Fundamentals
Java Course - Mastering the Fundamentals
by Tarun Luthra
1000
5
Start Learning
Topics Covered

The finalize() method in Java is a method of the Object class used to perform cleanup activity before destroying any object. Garbage collector calls it before destroying the objects from memory. finalize method in Java is called by default for every object before its deletion. This method helps the Garbage Collector close all the resources the object uses and helps JVM in-memory optimization.

Syntax

As mentioned earlier, finalize() is a protected method of the Object class in Java. Here is the syntax:

  • Protected method: protected is an access specifier for variables and methods in Java. When a variable or method is protected, it can be accessed within the class where it's declared and other derived classes of that class.

  • all classes inherit the Object class directly or indirectly in Java. The finalize() method is protected in the Object class so that all classes in Java can override and use it.

Why finalize() Method is Used?

Before the Garbage collector deletes the object, the finalize() method in Java releases all the resources the object uses. Once the finalize method performs its work then, the garbage collector immediately eliminates the Java object. Java Virtual Machine(JVM) permits invoking of finalize() method only once per object.

When to Use finalize() Method in Java?

  • Garbage collection is done automatically in Java, which the JVM handles. Java uses the finalize method to release the resources of the object that has to be destroyed.
  • GC call the finalize method only once, if an exception is thrown by finalizing method or the object revives itself from finalize(), the garbage collector will not call the finalize() method again.
  • It's not guaranteed whether or when the finalized method will be called. Relying entirely on finalization to release resources is not recommended.
  • There are other ways to release the resources used in Java, like the close() method for file handling or the destroy() method. But, the issue with these methods is they don't work automatically, we have to call them manually every time.
  • In such cases, to improve the chances of performing clean-up activity, we can use the finalize() method in the final block. finally block will execute finalize() method even though the user has used close() method manually.
  • We can use the finalize() method to release all the resources used by the object.* In the final block, we can override the finalize() method.* An example of overriding the finalize method in Java is given in the next section of this article.

Overriding in Java

Let's quickly understand what method overrides in Java.

  • Overriding is a feature in Java, where parent class(superclass) methods can be reimplemented in child classes(subclass).
  • When overriding any parent class method, the name, return type, and parameters of the method should be the same in the child class.
  • In Java, the Object class serves as the root of the class hierarchy. Every class in Java is either a direct or indirect subclass of Object. Hence, Object class methods like the finalize() method can be overridden.

How to Override finalize() Method?

We know that finalize() is a protected method of the Object class of Java. The finalize() method in Java has an empty implementation. Hence, we can use it in our class by overriding it. The finalize() method can be overridden in our class because the Object class is the parent class of all the classes in Java. If our class has clean-up activities, then we have to override this method explicitly to perform our clean-up activities.

Example 1:

Here, let's see how we can override the finalize() method in the try-catch-finally block and call it explicitly.

Output:

Explanation:

  • In the above program, the finalize() method of the Object class is overridden in the Demo class. As mentioned earlier, every class defined is a subclass of the Object class in Java.
  • d is an object of the Demo class. When d.finalize(); is executed, the finalize() method in the Demo class is called, and executed and cleanup activities are performed for object d.
  • You will notice that super.finalize() is called in the finally block of try-catch-finally blocks. It ensures execution of the finalize() method even if an exception occurs.

Statements that can raise any exception are mentioned in a try block. If an exception is caught, a catch block will handle it. Whether an exception occurs or not, the finally block will execute the finalize() method.

Example 2:

In this example, we will show we can destroy objects explicitly using Garbage Collector, which in turn will call overridden finalize() method.

Output:

Explanation:

In the above example, ex is an object of the example class that is unreferenced and destroyed by the garbage collector. This garbage collector is called the overridden finalize method in Java before destroying the object.

final vs finally vs finalize() in Java

Java has 3 different keywords used in different scenarios: final, finally, and finalize. These are different keywords with completely different functionalities. Let's understand their uses and differences:

finalfinallyfinalize
final is a keyword and access modifier in Java.finally block is used in Java Exception Handling to execute the mandatory piece of code after try-catch blocks.finalize() is the method in Java.
final access modifier is used to apply restrictions on the variables, methods, and classes.It executes whether an exception occurs or not. It is primarily used to close resources.The finalize() method performs clean-up processing just before garbage is collected from an object.
It is used with variables, methods, and classes.It is with the try-catch block in exception handling.It is used with objects.
Once declared, the final variable becomes constant and can't be modified.finally block cleans up all the resources used in the try block.finalize method in Java performs the cleaning concerning the object before its destruction.
final is executed only when we call it.finally block executes as soon as the execution of try-catch block is completed without depending on the exception.It is executed just before the object is destroyed.

How the finalize() Method Works in Different Scenarios

Now, let's see how the finalize() method behaves in different scenarios with the help of programs.

1. finalize() Method of Which Class is Being Called

Let's see examples where you want to override Java's finalize method() in a user-defined class. And try to garbage collect the unreferenced objects.

Example1:

Output:

Explanation:

As we can see, the program's output is Garbage collector is called. But the question is why it is not executing the overridden finalize() method defined in the Demo class.

**When an object in java becomes eligible for garbage collection, the garbage collector invokes its class's finalize method. In the above program, s1 = null; s1 is the object of the String class, not of the Demo class. So, when System.gc(); invokes the garbage collector, it calls the finalize() method of the String class in Java and the overridden finalize() method of the Demo class is not executed.

Example 2:

Output:

Explanation:

In this example, the s1 object is eligible for garbage collection. When System.gc(); invokes the garbage collector, it calls the object class's finalize() method. The overridden finalize() method of the Student class is called, and it prints Finalize method is called.

2. Explicit Call to finalize() Method

When we call the finalize() method explicitly, the JVM treats it as a normal method; it cannot remove the object from memory. The finalize() method can release memory and resources related to an object only when a Garbage collector calls it. Compiler will ignore the finalize() method if it's called explicitly and not invoked by the Garbage collector. Let's understand this practically:

Output:

Explanation:

In this example, when the finalize() method is called explicitly, it does not destroy the object demo2. But when System.gc() calls the finalize() method implicitly, it releases all the resources, and the Garbage collector destroys the object created in the first statement.

3. Exceptions in finalize() Method

If any exception occurs in the finalize() method, it is ignored by the Garbage Collector, and the finalize() method is not executed.

Output:

Explanation:

In this example, System.gc(); invokes the finalize() method, and the first print statement in the finalize() method is executed. But in the second statement, java.lang.ArithmeticException: / by zero is raised, and as soon as the exception is raised, GC stops executing the finalize() method.

Handling Exceptions in finalize() Method

We have seen that JVM ignores unchecked exceptions in the finalize() method. To overcome this, we can handle these unchecked exceptions using a try-catch block and ensure execution of the finalize() method.

Output:

Explanation:

In this case, the finalize() method is executed properly because the exception is handled itself in the catch block.

4. finalize() Method is Called Only Once for an Object

It has been mentioned earlier that the Garbage collector invokes the finalize() method only once for an object. Even if the object has been revived, JVM doesn't allow the call finalize() method to be used again for the same object. Let's see this practically.

Output:

Explanation:

We can see that the second time the Garbage collector is invoked, it doesn't execute the finalize method.

Best Practices to Use finalize() Method Correctly

Try to avoid the use of the finalize method. In case you need to use it, the following are points to remember while using the finalize() method:

  1. Do not use the finalize() method to execute time-critical application logic, as the execution of the finalize method cannot be predicted.
  2. Call the super.finalize() method in the finally block; it will ensure that the finalize method will be executed even if any exception is caught. Refer to the following finalize() method template:
  1. Never use Runtime.runFinalizersOnExit(true) because it can harm your entire system.

Conclusion

  • finalize() is an Object class method in Java, and it can be used in all other classes by overriding it.
  • The garbage collector uses the finalize() method to complete the clean-up activity before destroying the object.
  • JVM allows invoking of the finalize() method in Java only once per object.
  • Garbage collection is automated in Java and controlled by JVM.
  • Garbage Collector calls the finalize method in java of that class whose object is eligible for Garbage collection.