Skip to content

9.3. Finally Block

The finally block is used to execute important code such as resource cleanup, regardless of whether an exception occurs or not. It's guaranteed to execute (with few exceptions).

Finally Block Syntax

java
try {
    // Code that might throw exception
} catch (ExceptionType e) {
    // Exception handling
} finally {
    // Code that always executes
    cleanupResources();
}

When Finally Executes

The finally block executes in these scenarios:

  1. No exception occurs in try block
  2. Exception occurs and is caught by catch block
  3. Exception occurs and is not caught by any catch block
  4. Return statement in try or catch block
  5. Break/continue in loops

Resource Cleanup Example

java
public class ResourceManager {
    public void readFile() {
        FileReader reader = null;
        try {
            reader = new FileReader("data.txt");
            // Read file content
            System.out.println("File read successfully");

        } catch (FileNotFoundException e) {
            System.out.println("File not found: " + e.getMessage());

        } finally {
            // Always close the resource
            if (reader != null) {
                try {
                    reader.close();
                    System.out.println("File reader closed");
                } catch (IOException e) {
                    System.out.println("Error closing file: " + e.getMessage());
                }
            }
        }
    }
}

Try-With-Resources (Java 7+)

Java 7 introduced try-with-resources which automatically closes resources that implement AutoCloseable.

java
public class ModernResourceManager {
    public void readFile(String filename) {
        // Resource automatically closed after try block
        try (FileReader reader = new FileReader(filename);
             BufferedReader br = new BufferedReader(reader)) {

            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }

        } catch (IOException e) {
            System.out.println("Error reading file: " + e.getMessage());
        }
        // No finally block needed for resource cleanup
    }
}

Finally with Return Statements

java
public class FinallyReturnExample {
    public int testFinally() {
        try {
            System.out.println("In try block");
            return 1;  // This return is "delayed" until finally executes

        } catch (Exception e) {
            System.out.println("In catch block");
            return 2;

        } finally {
            System.out.println("In finally block");
            // This executes before the return statement
        }
    }

    public static void main(String[] args) {
        FinallyReturnExample example = new FinallyReturnExample();
        int result = example.testFinally();
        System.out.println("Returned: " + result);
    }
}

Output:

In try block
In finally block
Returned: 1

Complete Example: Database Connection

java
import java.sql.*;

public class DatabaseExample {
    public void queryDatabase(String sql) {
        Connection conn = null;
        Statement stmt = null;

        try {
            // Establish database connection
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "pass");
            stmt = conn.createStatement();

            // Execute query
            ResultSet rs = stmt.executeQuery(sql);

            // Process results
            while (rs.next()) {
                System.out.println(rs.getString("name"));
            }

        } catch (SQLException e) {
            System.out.println("Database error: " + e.getMessage());

        } finally {
            // Always close database resources
            try {
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
                System.out.println("Database resources closed");
            } catch (SQLException e) {
                System.out.println("Error closing resources: " + e.getMessage());
            }
        }
    }
}

When Finally Doesn't Execute

Finally block may not execute in these rare cases:

  • System.exit() is called
  • JVM crashes
  • Infinite loop in try block
  • Daemon thread termination

Best Practices

  1. Use try-with-resources for automatic resource management
  2. Keep finally blocks clean - avoid complex logic
  3. Don't throw exceptions from finally blocks
  4. Use for cleanup only - not for business logic