Posted on: January 18, 2025 Posted by: rahulgite Comments: 0

Final, Finally, and Finalize in Java

Java provides the keywords final, finally, and finalize, each serving a distinct purpose. Below is a detailed explanation of their usage, differences, and examples.


1. Final:

  • Definition:
    • The final keyword is used to apply restrictions on classes, methods, and variables.
  • Usage:
    1. Final Variable:
      • A final variable’s value cannot be changed once assigned.
     public class FinalVariableExample {
         public static void main(String[] args) {
             final int CONSTANT = 100;
             // CONSTANT = 200; // Error: Cannot reassign a final variable
             System.out.println(CONSTANT);
         }
     }
     
  1. Final Method:
    • A final method cannot be overridden by subclasses.
     class Parent {
         public final void display() {
             System.out.println("This is a final method.");
         }
     }

     class Child extends Parent {
         // Error: Cannot override the final method from Parent
         // public void display() { ... }
     }
     
  1. Final Class:
    • A final class cannot be subclassed.
     public final class FinalClass {
         public void display() {
             System.out.println("This is a final class.");
         }
     }

     // Error: Cannot subclass a final class
     // class SubClass extends FinalClass {}
     

2. Finally:

  • Definition:
    • The finally block is used to execute important code (like cleanup) regardless of whether an exception occurs or not.
  • Usage:
  public class FinallyExample {
      public static void main(String[] args) {
          try {
              int result = 10 / 0; // This will throw an ArithmeticException
          } catch (ArithmeticException e) {
              System.out.println("Exception caught: " + e.getMessage());
          } finally {
              System.out.println("Finally block is always executed.");
          }
      }
  }
  
  • Key Points:
    • The finally block is executed even if there is a return statement in the try or catch block.

3. Finalize:

  • Definition:
    • The finalize() method is called by the garbage collector before an object is destroyed.
  • Usage:
  public class FinalizeExample {
      @Override
      protected void finalize() throws Throwable {
          System.out.println("Finalize method called");
      }

      public static void main(String[] args) {
          FinalizeExample obj = new FinalizeExample();
          obj = null; // Make the object eligible for garbage collection
          System.gc(); // Request garbage collection
      }
  }
  
  • Key Points:
    • The finalize() method is rarely used in modern applications.
    • Use try-with-resources or explicit resource management instead of relying on finalize().

Comparison Table:

FeatureFinalFinallyFinalize
DefinitionUsed to apply restrictions.Ensures cleanup after exceptions.Invoked before object destruction.
Applies ToVariables, methods, and classes.try-catch-finally blocks.Objects eligible for garbage collection.
PurposePrevent modification/overriding.Guarantee code execution.Cleanup before object removal.
When UsedDuring design/declaration.During exception handling.Automatically by JVM.

Try-With-Resources in Java

The try-with-resources statement in Java is a powerful feature introduced in Java 7 that simplifies resource management by ensuring that resources are automatically closed after their usage. Resources like files, sockets, or database connections implement the AutoCloseable interface and can be used within this statement.

Syntax

try (ResourceType resource = new ResourceType()) {
    // Use the resource
} catch (ExceptionType e) {
    // Handle exception
} finally {
    // Optional cleanup code
}

How it Works

  • Resources declared inside the parentheses of the try block are automatically closed at the end of the block.
  • The close() method of the resource is called, ensuring proper cleanup.
  • This eliminates the need for a finally block to close resources explicitly.

Example 1: Reading a File

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TryWithResourcesExample {
    public static void main(String[] args) {
        try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

In this example:

  • A BufferedReader is opened to read a file.
  • The reader resource is automatically closed when the try block is exited, even if an exception occurs.

Example 2: Database Connection

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DatabaseExample {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/mydatabase";
        String user = "root";
        String password = "password";

        try (Connection conn = DriverManager.getConnection(url, user, password);
             PreparedStatement stmt = conn.prepareStatement("SELECT * FROM employees");
             ResultSet rs = stmt.executeQuery()) {

            while (rs.next()) {
                System.out.println("Employee ID: " + rs.getInt("id") + ", Name: " + rs.getString("name"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

In this example:

  • Multiple resources (Connection, PreparedStatement, ResultSet) are declared in the try-with-resources statement.
  • All resources are closed automatically in reverse order of their declaration.

Benefits

  1. Simplifies Code: Reduces boilerplate code by eliminating the need for explicit resource closure.
  2. Avoids Resource Leaks: Ensures that resources are properly closed, even in the presence of exceptions.
  3. Improves Readability: Makes the code easier to understand and maintain.

Important Notes

  1. Resource Scope: Resources declared in the try-with-resources statement are limited to the scope of the try block.
  2. AutoCloseable Interface: Custom resources must implement the AutoCloseable or Closeable interface to be used with try-with-resources.

Example of a Custom Resource

class CustomResource implements AutoCloseable {
    public void useResource() {
        System.out.println("Using custom resource.");
    }

    @Override
    public void close() {
        System.out.println("Custom resource closed.");
    }
}

public class CustomResourceExample {
    public static void main(String[] args) {
        try (CustomResource resource = new CustomResource()) {
            resource.useResource();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Output:

Using custom resource.
Custom resource closed.

Leave a Comment