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.