← Back to Home

finally Block

The finally block in Java is used to execute important cleanup code regardless of whether an exception occurs or not. It ensures that critical resources are released, making programs safe and reliable.

This is a high-frequency interview topic, often asked with tricky edge cases.

What Is the finally Block?

  • Always executes after try and catch
  • Used for cleanup operations
  • Executes whether exception occurs or not
  • Ensures program stability

Basic Syntax

try {
    // risky code
} catch (Exception e) {
    // handling code
} finally {
    // cleanup code
}
          

Why finally Is Important

  • Closes resources (files, DB, network)
  • Releases memory
  • Restores system state
  • Avoids resource leaks
  • Ensures predictable execution

Basic Example

try {
    int a = 10 / 2;
} catch (ArithmeticException e) {
    System.out.println("Error");
} finally {
    System.out.println("Finally block executed");
}
          

Output:

Finally block executed
          

Result: ✔ Executes even when no exception occurs

Execution Scenarios (Very Important)

1️⃣ No Exception Occurs

try {
    int x = 10 / 2;
} catch (Exception e) {
} finally {
    System.out.println("Finally");
}
          

✔ finally executes

2️⃣ Exception Occurs and Is Caught

try {
    int x = 10 / 0;
} catch (ArithmeticException e) {
} finally {
    System.out.println("Finally");
}
          

✔ finally executes

3️⃣ Exception Occurs and Is NOT Caught

try {
    int x = 10 / 0;
} finally {
    System.out.println("Finally");
}
          

✔ finally executes

❌ Program terminates after finally

Can finally Exist Without catch?

✔ Yes

try {
    int x = 10 / 2;
} finally {
    System.out.println("Cleanup");
}
          

❌ catch is optional

✔ finally is optional

When finally Does NOT Execute (Rare but Important)

1. System.exit() is Called

try {
    System.exit(0);
} finally {
    System.out.println("Finally");
}
          

❌ finally will NOT execute

2. JVM Crash / Power Failure

  • JVM shuts down unexpectedly
  • finally cannot run

return Statement and finally

Example

int test() {
    try {
        return 10;
    } finally {
        System.out.println("Finally");
    }
}
          

✔ Output:

Finally
          

✔ Method returns 10 after finally

return in finally (Very Dangerous)

int test() {
    try {
        return 10;
    } finally {
        return 20;
    }
}
          

❌ Output:

20
          
  • ⚠️ finally overrides return value
  • ⚠️ Strongly discouraged

finally vs try-with-resources

Traditional Cleanup

FileReader fr = null;
try {
    fr = new FileReader("file.txt");
} finally {
    if (fr != null) fr.close();
}
          

Modern Approach (Java 7+)

try (FileReader fr = new FileReader("file.txt")) {
    // use file
}
          
  • ✔ Automatic resource cleanup
  • ✔ Cleaner and safer

Common Beginner Mistakes

  • Writing business logic in finally
  • Using return inside finally
  • Forgetting that finally always executes
  • Not handling resource cleanup properly
  • Assuming finally always executes (ignoring System.exit)

Interview-Ready Answers

Short Answer

The finally block is used to execute cleanup code whether an exception occurs or not.

Detailed Answer

In Java, the finally block is executed after try and catch blocks regardless of whether an exception is thrown or handled. It is typically used for resource cleanup such as closing files or database connections. The only cases where finally does not execute are JVM termination or system exit.

Key Takeaway

finally guarantees cleanup. Use it for resource release, not for business logic. Avoid return inside finally to prevent unexpected behavior.

finally Block Examples (Interview Favorites)

1. Basic finally Execution

class Demo {
    public static void main(String[] args) {
        try {
            int a = 10 / 0;
        } catch (ArithmeticException e) {
            System.out.println("Catch");
        } finally {
            System.out.println("Finally");
        }
    }
}
          

Output

Catch
Finally
          

2. finally Without Exception

class Demo {
    public static void main(String[] args) {
        try {
            System.out.println("Try block");
        } finally {
            System.out.println("Finally block");
        }
    }
}
          

Output

Try block
Finally block
          

3. finally Without catch

class Demo {
    public static void main(String[] args) {
        try {
            System.out.println("Only try");
        } finally {
            System.out.println("Only finally");
        }
    }
}
          

Output

Only try
Only finally
          

4. finally with Multiple catch

class Demo {
    public static void main(String[] args) {
        try {
            String s = null;
            s.length();
        } catch (ArithmeticException e) {
            System.out.println("Arithmetic");
        } catch (NullPointerException e) {
            System.out.println("Null");
        } finally {
            System.out.println("Finally executed");
        }
    }
}
          

Output

Null
Finally executed
          

5. finally Executes Even After return

class Demo {
    static int test() {
        try {
            return 10;
        } finally {
            System.out.println("Finally");
        }
    }

    public static void main(String[] args) {
        System.out.println(test());
    }
}
          

Output

Finally
10
          

6. finally Overrides return (Interview Favorite)

class Demo {
    static int test() {
        try {
            return 10;
        } finally {
            return 20;
        }
    }

    public static void main(String[] args) {
        System.out.println(test());
    }
}
          

Output

20
          

7. finally with Exception + return

class Demo {
    static int test() {
        try {
            int a = 10 / 0;
            return 1;
        } catch (ArithmeticException e) {
            return 2;
        } finally {
            return 3;
        }
    }

    public static void main(String[] args) {
        System.out.println(test());
    }
}
          

Output

3
          

8. finally Executes When Exception Not Caught

class Demo {
    public static void main(String[] args) {
        try {
            int a = 10 / 0;
        } finally {
            System.out.println("Finally executed");
        }
    }
}
          

Output

Finally executed
Exception in thread "main" java.lang.ArithmeticException
          

9. finally with Nested try-catch

class Demo {
    public static void main(String[] args) {
        try {
            try {
                int a = 10 / 0;
            } catch (ArithmeticException e) {
                System.out.println("Inner catch");
            }
        } finally {
            System.out.println("Outer finally");
        }
    }
}
          

Output

Inner catch
Outer finally
          

10. finally and Resource Cleanup (Old Style)

import java.io.FileInputStream;

class Demo {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("test.txt");
        } catch (Exception e) {
            System.out.println("Exception");
        } finally {
            try {
                if (fis != null) fis.close();
                System.out.println("Resource closed");
            } catch (Exception e) {}
        }
    }
}
          

Output

Exception
Resource closed
          

11. finally vs try-with-resources

import java.io.*;

class Demo {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("test.txt")) {
            System.out.println("Using resource");
        } catch (Exception e) {
            System.out.println("Exception");
        }
    }
}
          

Explanation

Resource auto-closed (no finally needed)

12. finally Not Executed with System.exit()

class Demo {
    public static void main(String[] args) {
        try {
            System.exit(0);
        } finally {
            System.out.println("Finally");
        }
    }
}
          

Explanation

JVM terminates immediately

finally not executed

13. finally Not Executed on JVM Crash

class Demo {
    public static void main(String[] args) {
        try {
            Runtime.getRuntime().halt(0);
        } finally {
            System.out.println("Finally");
        }
    }
}
          

Explanation

JVM halt → no cleanup

14. finally with throw

class Demo {
    static void test() {
        try {
            throw new RuntimeException();
        } finally {
            System.out.println("Finally");
        }
    }

    public static void main(String[] args) {
        test();
    }
}
          

Output

Finally
Exception in thread "main" java.lang.RuntimeException
          

15. finally with throw Overrides Exception

class Demo {
    static void test() {
        try {
            throw new ArithmeticException();
        } finally {
            throw new NullPointerException();
        }
    }

    public static void main(String[] args) {
        test();
    }
}
          

Explanation

finally exception overrides try exception

16. finally with Loop

class Demo {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++) {
            try {
                System.out.println(i);
            } finally {
                System.out.println("Finally");
            }
        }
    }
}
          

Output

1
Finally
2
Finally
3
Finally
          

17. finally in Method Call Stack

class Demo {
    static void m1() {
        try {
            m2();
        } finally {
            System.out.println("Finally in m1");
        }
    }

    static void m2() {
        int a = 10 / 0;
    }

    public static void main(String[] args) {
        try {
            m1();
        } catch (Exception e) {
            System.out.println("Exception caught");
        }
    }
}
          

Output

Finally in m1
Exception caught
          

18. finally with break

class Demo {
    public static void main(String[] args) {
        while (true) {
            try {
                break;
            } finally {
                System.out.println("Finally");
            }
        }
    }
}
          

Output

Finally
          

19. finally with continue

class Demo {
    public static void main(String[] args) {
        for (int i = 1; i <= 2; i++) {
            try {
                continue;
            } finally {
                System.out.println("Finally " + i);
            }
        }
    }
}
          

Output

Finally 1
Finally 2
          

20. Interview Summary – finally Block

class Demo {
    public static void main(String[] args) {
        try {
            int a = 10 / 0;
        } catch (Exception e) {
            System.out.println("Catch");
        } finally {
            System.out.println("Cleanup");
        }
    }
}
          

Key Points

  • Executes almost always
  • Used for cleanup
  • Overrides return and exceptions if present
  • Not executed only on JVM termination

Output

Catch
Cleanup