The finally block will always execute, except for System.exit() is called first, or the thread has terminated or the JVM crashes. Anything that is returned in the finally block will actually override any exception or returned value that is inside the try/catch block.


public class Finally {

    //exception-free code, try-catch-finally blocks all have returns
    private int scenario1() {
        int i = 0;
        try {
            System.out.println("Inside try block of testMethod!");
            i = 100;
            return i;
        } catch(Exception e){
            System.out.println("Inside catch block of testMethod!");
            i = 200;
            return i;
        } finally{
            System.out.println("Inside finally block of testMethod!");
            i = 300;
            return i;
        }
    }

    //try block throws exception, try-catch blocks all have returns
    private int scenario2() {
        int i = 0;
        try {
            System.out.println("Inside try block of testMethod!");
            i = 100/0;
            return i;
        } catch(Exception e){
            System.out.println("Inside catch block of testMethod!");
            i = 200;
            return i;
        } finally{
            System.out.println("Inside finally block of testMethod!");
            i = 300;
            //return i;
        }
    }

    //try-catch blocks throw exception, try-catch-finally blocks all have returns
    private int scenario3() {
        int i = 0;
        try {
            System.out.println("Inside try block of testMethod!");
            i = 100/0;
            return i;
        } catch(Exception e){
            System.out.println("Inside catch block of testMethod!");
            i = 200/0;
            return i;
        } finally{
            System.out.println("Inside finally block of testMethod!");
            i = 300;
            return i;
        }
    }

    //try block throws exception, try-catch-finally blocks all have returns
    private int scenario4() {
        int i = 0;
        try {
            System.out.println("Inside try block of testMethod!");
            i = 100/0;
            return i;
        } catch(Exception e){
            System.out.println("Inside catch block of testMethod!");
            i = 200;
            return i;
        } finally{
            System.out.println("Inside finally block of testMethod!");
            i = 300;
            return i;
        }
    }

    //try-catch blocks throw exception, try-catch blocks all have returns
    private int scenario5() {
        int i = 0;
        try {
            System.out.println("Inside try block of testMethod!");
            i = 100/0;
            return i;
        } catch(Exception e){
            System.out.println("Inside catch block of testMethod!");
            i = 200/0;
            return i;
        } finally{
            System.out.println("Inside finally block of testMethod!");
            i = 300;
            //return i;
        }
    }

    //try-catch-finally blocks throw exception, try-catch-finally blocks all have returns
    private int scenario6() {
        int i = 0;
        try {
            System.out.println("Inside try block of testMethod!");
            i = 100/0;
            return i;
        } catch(Exception e) {
            System.out.println("Inside catch block of testMethod!");
            i = 200/0;
            return i;
        } finally{
            System.out.println("Inside finally block of testMethod!");
            i = 300;
            return i/0;
        }
    }

    //try and catch both fine; finally throws exception
    private int scenario7() {
        int i = 0;
        try {
            System.out.println("Inside try block of testMethod!");
            i = 100;
            return i;
        } catch(Exception e){
            System.out.println("Inside catch block of testMethod!");
            i = 200;
            return i;
        } finally{
            System.out.println("Inside finally block of testMethod!");
            i = 300;
            return i/0;
        }
    }

    //try and catch both fine; finally doesn't have any return
    private int scenario8() {
        int i = 0;
        try {
            System.out.println("Inside try block of testMethod!");
            i = 100;
            return i;
        } catch(Exception e){
            System.out.println("Inside catch block of testMethod!");
            i = 200;
            return i;
        } finally{
            System.out.println("Inside finally block of testMethod!");
            i = 300;
            //return i;
        }
    }

    @Test
    public void testPlayWithFinally() {
        System.out.println("\n-----------Senrio1------------------");
        System.out.println("Return value: " + scenario1());

        System.out.println("\n-----------Senrio2------------------");
        System.out.println("Return value: " + scenario2());

        System.out.println("\n-----------Senrio3------------------");
        System.out.println("Return value: " + scenario3());

        System.out.println("\n-----------Senrio4------------------");
        System.out.println("Return value: " + scenario4());

//        System.out.println("\n-----------Senrio5------------------");
//        System.out.println("Return value: " + scenario5());

//        System.out.println("\n-----------Senrio6------------------");
//        System.out.println("Return value: " + scenario6());

//        System.out.println("\n-----------Senrio7------------------");
//        System.out.println("Return value: " + scenario7());

        System.out.println("\n-----------Senrio8------------------");
        System.out.println("Return value: " + scenario8());

    }
}

/* ———–Senrio1—————— Inside try block of testMethod! Inside finally block of testMethod! Return value: 300

———–Senrio2—————— Inside try block of testMethod! Inside catch block of testMethod! Inside finally block of testMethod! Return value: 200

———–Senrio3—————— Inside try block of testMethod! Inside catch block of testMethod! Inside finally block of testMethod! Return value: 300

———–Senrio4—————— Inside try block of testMethod! Inside catch block of testMethod! Inside finally block of testMethod! Return value: 300

———–Senrio5—————— Inside try block of testMethod! Inside catch block of testMethod! Inside finally block of testMethod!

java.lang.ArithmeticException: / by zero

———–Senrio6—————— Inside try block of testMethod! Inside catch block of testMethod! Inside finally block of testMethod!

java.lang.ArithmeticException: / by zero

———–Senrio7—————— Inside try block of testMethod! Inside finally block of testMethod!

java.lang.ArithmeticException: / by zero

———–Senrio8—————— Inside try block of testMethod! Inside finally block of testMethod! Return value: 100 */