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:
- No exception occurs in try block
- Exception occurs and is caught by catch block
- Exception occurs and is not caught by any catch block
- Return statement in try or catch block
- 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: 1Complete 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
- Use try-with-resources for automatic resource management
- Keep finally blocks clean - avoid complex logic
- Don't throw exceptions from finally blocks
- Use for cleanup only - not for business logic
