Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
What is the Finalize Method in Java?
3.
Garbage Collector in Java
4.
How does the Finalize Method in Java Work with Garbage Collection?
5.
Syntax of Finalize Method in Java
6.
Why finalize() method in Java is used?
7.
When to Use finalize() Method in Java?
8.
How to Override finalize() method?
8.1.
Java
9.
Working of Finalize() Method in Different Scenarios
9.1.
Case 1: Object is garbage collected, but no finalize() method is defined
9.2.
Java
9.3.
Case 2: Object is garbage collected, and a finalize() method is defined
9.4.
Java
9.5.
Case 3: Exception in finalize() method 
9.6.
Java
10.
Handling Exceptions in Finalize () Method
11.
The Lifetime of the Finalized Object in Java
11.1.
1. Object is created
11.2.
2. Object becomes eligible for garbage collection
11.3.
3. Finalize method is called
11.4.
4. Object is removed from memory
12.
Final vs Finally vs finalize() in Java
13.
Advantages of Finalize Method in Java
14.
Disadvantages of Finalize Method in Java
15.
Alternatives to Finalize() Method in Java
16.
Best Practices to Use Finalize() Method in Java Correctly
17.
Frequently Asked Questions
17.1.
What is the purpose of the finalize() method in Java?
17.2.
When is the finalize() method called?
17.3.
What is the difference between final & finalize in Java? 
17.4.
How many times can finalize method be called in Java? 
17.5.
What is the difference between finalize and GC in Java?
18.
Conclusion
Last Updated: Mar 28, 2024
Medium

Finalize() Method in Java

Author Nilesh Kumar
0 upvote
Create a resume that lands you SDE interviews at MAANG
Speaker
Anubhav Sinha
SDE-2 @
12 Jun, 2024 @ 01:30 PM

Introduction

Hey, Ninjas! In this article, we'll discuss the finalize method in Java. In Java, an object no longer being used or referenced becomes eligible for garbage collection. However, before the object is removed from memory, the garbage collector calls the finalize () method. This method allows the object to perform any necessary cleanup operations before it is destroyed. 

finalize method in java

The finalize() method is a protected method defined in the Object class, the superclass of all Java classes. Any class can override the finalize() method to add its custom cleanup code. So without further ado, let's start!

What is the Finalize Method in Java?

The finalize() method in Java is a protected method defined in the Object class, which is the superclass of all Java classes. It allows an object to perform any necessary cleanup operations before the garbage collector destroys it. When an object is no longer used or referenced, it becomes eligible for garbage collection. Before it is removed from memory, the garbage collector calls the finalize() method on the object. If the object has overridden the finalize() method, any custom cleanup code specified in that method will be executed.

To use the finalize() method in a class, you must override it with your implementation. In your implementation, you can include any necessary cleanup code, such as closing open files or releasing other resources.

However, there are some pitfalls to using the finalize() method. For example, it is not guaranteed to be called, and there is no way to know when it will be called. The finalize() method can also cause performance issues if it takes too long to execute.

Get the tech career you deserve, faster!
Connect with our expert counsellors to understand how to hack your way to success
User rating 4.7/5
1:1 doubt support
95% placement record
Akash Pal
Senior Software Engineer
326% Hike After Job Bootcamp
Himanshu Gusain
Programmer Analyst
32 LPA After Job Bootcamp
After Job
Bootcamp

Garbage Collector in Java

In Java, the Garbage Collector (GC) is a program that automatically manages the memory used by Java programs. The GC tracks object no longer being used or referenced by the program and free up memory by removing those objects. The GC works by periodically scanning the heap memory for objects that are no longer referenced by the program. If it finds any such objects, it frees up the memory occupied by those objects. This process is called garbage collection.

Java provides several different algorithms for garbage collection, each with its strengths and weaknesses. The most common algorithm the JVM uses is the mark-and-sweep algorithm, which works by identifying all objects that are no longer reachable by the program and then freeing up the memory occupied by those objects. One of the advantages of using a GC is that it eliminates the need for manual memory management, which can be error-prone and time-consuming. However, the GC does add some overhead to the program, which can affect its performance.

How does the Finalize Method in Java Work with Garbage Collection?

The Garbage Collector (GC) automatically manages memory by freeing up memory occupied by unused objects. The GC calls the finalize() method before an object is removed from memory, allowing it to perform any necessary cleanup operations.

However, the finalize() method can have performance implications and should be used cautiously. 

Example code for overriding the finalize() method:


public class MyObject {
    private File file;

    public MyObject(String filename) {
        this.file = new File(filename);
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            if (file != null) {
                file.close();
            }
        } finally {
            super.finalize();
        }
    }

    // Other methods here
}

 

In this example, the MyObject class represents an object that holds a reference to a File object. The finalize() method is overridden to close the file before the GC removes the object from memory.

Syntax of Finalize Method in Java

Here's the syntax for the finalize() method:

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


Parameters

The finalize() method takes no arguments and has a void return type. It is declared protected to ensure that it can only be called by the garbage collector or by a subclass of the class that defines the finalize() method.

Return Value

The finalize() method does not return any value.

Why finalize() method in Java is used?

The finalize() method in Java is used for tasks such as closing external resources like files or network connections held by an object before it's garbage collected, releasing native resources to prevent leaks, and implementing custom cleanup logic. However, it's worth noting that as of Java 9, finalize() has been deprecated in favour of more modern resource management techniques like try-with-resources, considered more reliable beyond Java 8.

When to Use finalize() Method in Java?

The garbage collector calls the finalize () method before an object is reclaimed or destroyed. It can be used when you need to tidy up or release resources associated with an object. However, it is essential to note that the finalize() method has been deprecated, and its usage is discouraged. It is generally advised to employ alternative mechanisms for resource cleanup, like implementing the AutoCloseable interface and utilizing the try-with-resources statement. These alternative approaches provide improved control and ensure a predictable and reliable cleanup of resources, making them the preferred and recommended approach.

How to Override finalize() method?

To override the finalize() method in Java, and you can define your own implementation of the method in your class. This allows you to provide custom cleanup behavior for objects of that class.

When you override finalize(), you should include any necessary cleanup code within a try block and call super.finalize() in a finally block to ensure that any necessary cleanup is performed before the object is garbage collected.

Here's an example of how to override the finalize() method in Java:

  • Java

Java

public class MyClass {
   private int id;

   public MyClass(int id) {
       this.id = id;
   }

   @Override
   protected void finalize() throws Throwable {
       System.out.println("Object with id " + id + " is being destroyed");
       super.finalize();
   }

   public static void main(String[] args) {
       MyClass obj1 = new MyClass(1);
       MyClass obj2 = new MyClass(2);
       MyClass obj3 = new MyClass(3);

       obj1 = null;
       obj2 = null;

       // calling garbage collector explicitly
       System.gc();

       obj3 = null;

       // calling garbage collector explicitly
       Runtime.getRuntime().gc();
   }
}

 

Output

Object with id 1 is being destroyed
Object with id 2 is being destroyed

 

In this example, we create three instances of MyClass and then set obj1 and obj2 to null, so they are eligible for garbage collection. We then call the garbage collector explicitly using System.gc() and Runtime.getRuntime().gc().

When the garbage collector runs, it will call the finalize() method on any objects that are eligible for garbage collection. In this case, it will call finalize() on obj1 and obj2. The program's output will be:

Working of Finalize() Method in Different Scenarios

Here are a few different cases to illustrate how the finalize() method works:

Case 1: Object is garbage collected, but no finalize() method is defined

In this case, the garbage collector will destroy the object without calling any finalize() method.

  • Java

Java

class MyClass {
   // No finalize() method defined
}

public class Test {
   public static void main(String[] args) {
       MyClass obj = new MyClass();
       obj = null;
       System.gc(); // Explicitly call the garbage collector
   }
}

 

Output

// No output

 

Case 2: Object is garbage collected, and a finalize() method is defined

In this case, the garbage collector will call the finalize() method before destroying the object.

  • Java

Java

class MyClass {
   protected void finalize() throws Throwable {
       System.out.println("Object destroyed");
   }
}

public class Test {
   public static void main(String[] args) {
       MyClass obj = new MyClass();
       obj = null;
       System.gc(); // Explicitly call the garbage collector
   }
}

 

Output

Object destroyed

 

Case 3: Exception in finalize() method 

In this case, the garbage collector will continue with the destruction of the object, but the exception will be logged to the console.

  • Java

Java

class MyClass {
   protected void finalize() throws Throwable {
       throw new Exception("Exception in finalize() method");
   }
}

public class Test {
   public static void main(String[] args) {
       MyClass obj = new MyClass();
       obj = null;
       System.gc(); // Explicitly call the garbage collector
   }
}

 

Output

Exception in thread "Finalizer" java.lang.Exception: Exception in finalize() method
at MyClass.finalize(MyClass.java:3)
at java.base/java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
at java.base/java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:170)

 

As you can see, the exception is logged to the console with details of where it occurred.

Handling Exceptions in Finalize () Method

When the garbage collector calls the finalize() method, it has a specific way of handling exceptions. If an exception occurs while the finalize() method is running, it is usually caught and logged somewhere to keep a record of it. However, the exception itself is not thrown again.  This is because the garbage collector calls the finalize() method automatically, and throwing an exception from there can cause some unexpected issues.

The Lifetime of the Finalized Object in Java

In Java, the lifetime of an object with a finalize() method goes through several phases. Here are the phases through which a finalized object passes through its lifetime:

1. Object is created

When an object is created, it is in the "live" phase. The object is allocated memory and can be accessed by the program.

2. Object becomes eligible for garbage collection

When any part of the program no longer references an object, it becomes eligible for garbage collection. At this point, the object enters the "finalizable" phase.

3. Finalize method is called

When the garbage collector determines that an object is eligible for garbage collection, it calls the object's finalize() method before reclaiming its memory. The object is in the "finalized" phase during this process.

4. Object is removed from memory

After the finalize() method completes, the object is removed from memory and enters the "unreachable" phase. The object is no longer accessible, and its memory is eligible for reuse by the JVM.

Lifetime of the Finalized object

If the finalize() method resurrects the object by creating a new reference to it, the object will remain in the "finalizable" phase until the finalize() method completes. The object will then re-enter the "live" phase and continue to exist until it becomes eligible for garbage collection again.

Final vs Finally vs finalize() in Java

Below is the table providing the Key differences between the three methods:

FeatureFinalFinallyfinalize()
TypeKeywordKeywordMethod
PurposeTo restrict the modification of a variable, method, or class.To ensure that a section of code is always executed, even if an exception is thrown.To perform cleanup processing on an object before it is garbage collected.
ScopeCan be used with classes, methods, and variables.Can only be used with try/catch blocks.Can only be used with objects.
ExecutionChecked at compile time.Executed after the try/catch blocks, but before control transfers back to its origin.Executed just before an object is garbage collected.

Advantages of Finalize Method in Java

The finalize method in Java has some potential advantages, including

  • It can be used to perform cleanup operations on an object before it is garbage collected, such as releasing resources like file handles or network connections.
     
  • It provides a safety net for situations where a programmer may forget to manually clean up an object's resources, ensuring that the resources are eventually released even if the object is no longer referenced.
     
  • It can be used in cases where objects need to be "revived" or restored to a previous state after being garbage collected, although this usage is relatively rare.
     
  • It can be useful for debugging or profiling, as it allows you to monitor when objects are being garbage collected and potentially identify memory leaks or other issues.

Disadvantages of Finalize Method in Java

The finalize method has some potential drawbacks, including

  • It is not guaranteed to be called at any particular time or at all, so relying on it for critical cleanup operations can be risky.
     
  • It can introduce performance issues, as the JVM must perform additional work to manage finalization and resurrected objects.
     
  • It can make it more difficult to reason about the lifecycle of objects in a program, as the behavior of the finalize() method may not be immediately apparent.
     
  • It is generally recommended to use other cleanup mechanisms, such as try-with-resources blocks or explicit close() method calls, instead of relying on the finalize() method.

Alternatives to Finalize() Method in Java

Here are some alternatives to using the finalize() method:

  • Use the try-with-resources statement: This statement was introduced in Java 7 and makes it easy to manage resources that need to be closed when they are no longer needed. Resources that implement the AutoCloseable interface can be used in the try-with-resources statement, automatically calling the close() method on the resource
     
  • Use a shutdown hook: A shutdown hook is a thread executed when the JVM is shutting down. This can be used to perform any necessary cleanup before the JVM exits. To use a shutdown hook, you can define a class that extends the Thread class and override the run() method
     
  • Use a reference queue: A reference queue is a data structure that holds references to objects that have been garbage collected. By using a reference queue, you can perform cleanup actions on objects that are no longer needed
     
  • Use the PhantomReference class: PhantomReference is a special type of reference that gets added to a reference queue when the object it refers to is garbage collected. This can be useful for performing cleanup actions on objects that are no longer needed

Best Practices to Use Finalize() Method in Java Correctly

Best Practices for Correct Usage of the finalize() Method in Java are:

1. Be cautious: It is crucial to keep in mind that the finalize() method is not reliable in terms of when or even if it will be called by the garbage collector. This means relying on finalize() for critical operations or resource cleanup can be risky. Exploring alternative approaches like try-with-resources or implementing the Closeable or AutoCloseable interfaces is strongly recommended

2. Keep it simple: When implementing the finalize() method, it's best to keep it simple and lightweight. Avoid including complex operations, resource-intensive tasks, or any code that could throw exceptions.  Remember, the main purpose of finalize() is to handle basic cleanup operations, so it is important to focus on that

3. Avoid object resurrection: It's important to avoid using the finalize() method to bring objects back to life. In other words, we shouldn't try to make objects accessible again by resurrecting them through finalize(). Attempting to do so can cause confusion, make our program behave strangely, and lead to unpredictable results

4. Use super.finalize(): In the finalize() method implementation, It's important to remember to include super.finalize(). This helps ensure the superclass's finalization process is carried out correctly. By doing so, we maintain the expected behaviour of the class hierarchy and allow any essential cleanup tasks defined in the superclass to be performed

5. Consider alternatives: Instead of relying on the finalize() method, it's better to use explicit resource cleanup mechanisms like try-with-resources or implementing the Closeable or AutoCloseable interfaces. These newer approaches offer improved control and predictability when releasing resources

6. Prefer try-finally for cleanup: To ensure that resources are properly cleaned up. It is usually better to use a try-finally block or one of the alternative mechanisms mentioned earlier. These approaches ensure that cleanup operations are performed reliably, regardless of whether the finalize() method is called or not

7. Document intent: If you choose to use the finalize() method in your code, make sure to document its usage and limitations clearly. Explain why it is necessary and any specific precautions or requirements for it to work correctly

Frequently Asked Questions

What is the purpose of the finalize() method in Java?

The purpose of the finalize() method in Java is to perform cleanup tasks or release resources associated with an object before it gets reclaimed by the garbage collector, ensuring that necessary cleanup operations are carried out.

When is the finalize() method called?

The garbage collector calls the finalize () method when an object is ready to be reclaimed or destroyed. It offers a chance to tidy up or release any resources connected to the object. It ensures proper cleanup before removing it from memory.

What is the difference between final & finalize in Java? 

In Java, the keyword final indicates that a variable, method, or class cannot be modified or extended. On the other hand, the garbage collector calls the finalize () method before discarding an object. It allows it to perform necessary cleanup or resource release operations.

How many times can finalize method be called in Java? 

In Java, the finalize() method is called only once for an object during its lifetime. Once invoked by the garbage collector, it is removed from the finalization queue and will not be called again for that specific object.

What is the difference between finalize and GC in Java?

Finalize() method performs clean up activity and object is finalized. GC destroys the object completely and reclaims the space occupied by the object.

Conclusion

In this blog, we have discussed the finalize method in java along with the syntax, advantages, and disadvantages. We hope the blog has helped you enhance your knowledge regarding finalize method in Java. If you wish to learn more about Java, you can refer to blogs on 

Happy Learning!

Previous article
How to get started with Deep Java Library?
Next article
Non Primitive Data Types in Java
Live masterclass