What are the differences between finalize method, finally block, and final keyword in Java?

Java finalize Method

The finalize() method of a Java class is useful during garbage collection. Java does automatic garbage collection and periodically reclaims memory occupied by objects that are no longer referenced by any other object. If an object utilizes a resource other than memory, such as a file or a handle to another object that uses system resources then it is important that the resource should be freed before the object is reclaimed and recycled by garbage collector. A finalizer (finalize() method) added to any class is called before the garbage collector sweeps away the object. However, in practice we should not rely on the finalize() method for short supply resources because finalize() only guarantees that it will be called during garbage collection but when will garbage collector run, it depends upon system. So, if a resource needs to be closed as soon as you are done using it, you need to close it manually. Supply a method of your own for what needs to be immediately closed after use.

The signature of finalize() method must be as follows:

protected void finalize () throws throwable

Following is a trivial example demonstrating finalize() method. Class OpenFile opens a file when an instance is created.

class OpenFile 
{
  FileInputStream aFile = null;
  OpenFile(String filename) 
  {
    try 
    {
      aFile = new FileInputStream(filename);
    } 
    catch (java.io.FileNotFoundException e) 
    {
      System.err.println("Could not open file " + filename);
    }
  }
}

By using finalize(), an instance of OpenFile can close the file as follows.

protected void finalize () throws Throwable 
{
  if (aFile != null) 
  {
    aFile.close();
    aFile = null;
  }
}

The finalize() method is declared in the java.lang.Object class. Thus when you write a finalize() method for your class you are overriding the one in your superclass. If your class's superclass has a finalize() method, then your class's finalize() method should call the superclass's finalize() method after it has performed its clean up duties. This cleans up any resources the object may have unknowingly obtained through methods inherited from the superclass.

The most important thing we should keep in mind while using finalizers is:

After a finalizer is invoked, objects are not freed right away. This is because a finalizer method can resurrect an object by storing the this pointer somewhere so that the object once again has references. Thus, after finalize() is called, the garbage collector must once again determine that the object is unreferenced before it can garbage-collect it. However, even if an object is resurrected, the finalizer method is never invoked more than once. Resurrecting an object is never a useful thing to do -- just a strange quirk of object finalization. As of Java 1.2, the java.lang.ref.PhantomReference class can implement an alternative to finalization that does not allow resurrection.

Java finally Block

Java's finally block is useful in exception handling and always used in conjunction with try block. There should at least be one try block that finally block can be associated to. The try encloses a block of code in which exception may occur. When a piece of code throws an exception, it stops processing the remaining code in try block and transfers the control to an appropriate catch block. There can be more than one catch block associated to a single try block but only one catch block is processed at a time. Also note that the catch blocks immediately follow the try block.

So, exceptions are thrown from try block and caught by catch block then why finally needed and what is its purpose? Let us see that. Upon occurrence of an exception a method may decide to exit, which could be problematic, in case, the method has acquired some local resource that only it knows about and if that resource must be cleaned up before exiting the method. To tackle this problem Java provides finally clause. However, you can place the clean up code in catch blocks, but exception handlers (catch blocks) are a poor place to clean up after the code in the try block because each handler then requires its own copy of the clean up code. If, for example, you allocated a network resource or opened a file somewhere in the try block, each exception handler would have to close the file or release the resource. That would definitely lead to a lot of redundant code. To get rid of this problem, Java offers the finally block.

Piece of code contained by finally block is executed at some point after the try block, whether an exception is thrown or not. Even if there is a return statement in the try block, the finally block gets executed right after the return statement is encountered, and before the return gets executed.

If the try block gets executed with no exceptions, the finally block is executed immediately after the try block completes. If there was an exception thrown, the finally block gets executed immediately after the proper catch block completes. The finally block will not be executed if exit() is called before finally block is reached. The exit() call will shutdown the JVM, so no subsequent line of code will be run.

Remember, finally clauses are optional. If you don't code one, your program will compile and run just fine. You need not to code finally block if you have no resources to clean up. There will always be only one finally clause associated to a try block. In case of multiple try blocks you can have multiple finally clauses ensuring their proper association to try statements.

Java final Keyword

Most of the times you see Java's final keyword is used to define constants but there are other uses of final as well. Following is a list of uses of final keyword.

  • Using final to define constants: If you want to make a local variable, class variable (static field), or instance variable (non-static filed) constant, declare it final. A final variable may only be assigned to once and its value will not change and can help avoid programming errors.

    Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object.

    This also applies to arrays, because arrays are objects; if a final variable holds a reference to an array, then the components of the array may be changed by operations on the array, but the variable will always refer to the same array.

    This applies also to arrays, because arrays are objects; if a final variable holds a reference to an array, then the components of the array may be changed by operations on the array, but the variable will always refer to the same array.

  • Using final to prevent inheritance: If you find a class's definition is complete and you don't want it to be sub-classed, declare it final. A final class cannot be inherited, therefore, it will be a compile-time error if the name of a final class appears in the extends clause of another class declaration; this implies that a final class cannot have any subclasses.

    It is a compile-time error if a class is declared both final and abstract, because the implementation of such a class could never be completed.

    Because a final class never has any subclasses, the methods of a final class are never overridden

  • Using final to prevent overriding: When a class is extended by other classes, its methods can be overridden for reuse. There may be circumstances when you want to prevent a particular method from being overridden, in that case, declare that method final. Methods declared as final cannot be overridden.

  • Using final for method arguments: Formal parameters of a method can be declared final to prevent them from accidental changes during the execution of method body.

Hope you have enjoyed reading about finalize method, finally block and final keyword. Please do write us if you have any suggestion/comment or come across any error on this page. Thanks for reading!



Share this page on WhatsApp

Get Free Tutorials by Email

About the Author

is the founder and main contributor for cs-fundamentals.com. He is a software professional (post graduated from BITS-Pilani) and loves writing technical articles on programming and data structures.