简体   繁体   中英

Return statements in try/catch block Java

Suppose I have the following:

class NegativeException extends RuntimeException {
}

class ZeroException extends NegativeException {
}

class Driver {
    static boolean Marathon(int a) {
        try {
            if (a < 0)
                throw new NegativeException();
            else if (a == 0)
                throw new ZeroException();
            else if (a >= 42)
                return true;
            else
                return false;
        } catch (ZeroException e) {
            System.out.println("Use natural number");
        } finally {
            System.out.println("One last thing");
        }
        System.out.println("All done.");
        return false;
    }

    public static void main(String[] args) {
        /* One last thing */
        /* true */
        System.out.println(Marathon(100));


        System.out.println(Marathon(0));
        System.out.println(Marathon(-5));

    }
}

What I'm trying to understand is why doesn't the line "All done" not execute when use the first line of our main method is fired? Marathon(100)

It seems that the finally statement executes and THEN the return statement is outputted. I know that the finally block will always execute, regardless of what happens. However, I can't seem to grasp on how return statements affect the flow of the try catch blocks. Are there a set of rules that apply when trying to return from try-cath-finally blocks?

What I'm trying to understand is why doesn't the line "All done" not execute when use the first line of our main method is fired? Marathon(100)

Because a >= 42 is true, and so you do:

return true;

...which immediately transfers control to the finally block; at the end of the finally block, the function returns ( without running any lines following the finally block). That is, return doesn't just set a return value, it terminates the function at that point, after running any outstanding finally blocks.

If you want execution to continue, you'd write to a variable and then have a single return at the end:

static boolean Marathon(int a) {
    boolean rv = false;
    try {
        if (a < 0)
            throw new NegativeException();
        else if (a == 0)
            throw new ZeroException();
        else if (a >= 42)
            rv = true;
    } catch (ZeroException e) {
        System.out.println("Use natural number");
    } finally {
        System.out.println("One last thing");
    }
    System.out.println("All done.");
    return rv;
}

More on return within try and catch : If you issue a return from within a try that has a finally block, it immediately transfers control to the finally block. When the end of that block is reached, the function terminates ( without running any code after the finally block, unless you have nested finally blocks or similar). The same thing happens if you return from within a catch .

So for instance:

try {
    if (someCondition) {
        return 1;
    }
    if (someOtherCondition) {
        throw new Exception();
    }
}
catch (Exception e) {
    System.out.println("Got here because of exception");
    return 2;
}
finally {
    System.out.println("Got here");
}
System.out.println("May not have gotten here");
return 3;

"Got here" will always be output, no matter what; that's the point of finally clauses, they always get executed.

"Got here because of exception" will only be output if someOtherCondition is true (and will be output before "Got here" ), in which case the function returns normally with the value 1 .

"May not have gotten here" will not be output if either someCondition or someOtherCondition is true, because of the return s in the try and catch blocks.

If neither condition is true, you see "May not have gotten here" followed by "Got here" and the function returns 3 .

Note that the return in the catch block means that the function returns normally (with the value 2 ) when someOtherCondition is true, it doesn't throw. If you didn't have the return there and someOtherCondition were true, you'd see the "Got here because of exception" and the "Got here" and then the function would terminate with a throw (no return value at all), and would not output "May not have gotten here" .

Last but not least: If you have a return in a finally block, that return "wins": Even if you're in the finally block because you've already issued a return , a return in the finally block supercedes it, making the function return the value the finally said, not the earlier one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM