How finally block works? - java

hello community in my tutorial this week I found out that all threads stop when java gets a runtime error, but in the finally code block this event looks a bit strange.
public class main {
public static void main(String[] args) {
try {
Scanner kb = new Scanner(System.in);
System.out.println("enter number:");
double val = Double.parseDouble(kb.nextLine());
double result = MathUtil.myLog(val);
}
catch (MyException ex) {
System.out.println("Cath:foo");
}
finally {
System.out.println("foo:finally");
}
}
class MathUtil {
public static double myLog(double val)
{
if (val < 0)
throw new MyException();
if(val == 0)
throw new YourException();
return Math.log(val);
}
class MyException extends RuntimeException {
}
class YourException extends RuntimeException {
}
When i execute this code and make an incorrect entry it first executes the finally block and then I get runtimeError.

Works as indented, doesn't matter if catch clause catch an error, finally as it says will execute almost every time. It won't execute only if JVM runs out of memory but it's rare corner case

This works as designed :-) From the documantation from oracle:
'The finally block always executes when the try block exits..'
For me this means the finally block will be executed before the catch block or anything else is executed.

Related

Is return statement optional in a method that has return type not void, but throws an Exception?

Here I have a method that is expected to return a boolean :
static boolean display()
{
}
The compilation fails as This method must return a result of type boolean.
However, if the method is modified as below:
static boolean display()
{
try{
throw new ArithmeticException();
}
catch(ArithmeticException e)
{
throw e;
}
finally
{
System.out.println(finally);
}
}
Why does not the compilation fail anymore even though I have not added any return statement.
If in the catch block I do not include a throw statement, the compilation fails again with the previous reason.
The Java compiler does a (limited) flow analysis and when it can determine that all flows of control lead to an exception you don't need a return.
To understand try putting return true; at the end of the method. Then you should get a error calling unreachable statement.
This happens because your method always throwing an exception. So at the end you don't need to return a value, because it already throwing the exception before that and ends the method
You: Why does not the compilation fail anymore even though I have not added any return statement?
Answer: When you explicitly throw an exception in try block, and again
in the catch block you explicitly throw an exception, the compiler
does not give an error because you are throwing an exception
explicitly using the throw keyword, which terminates abruptly the
normal flow of code and stops the execution of all the subsequent code
in display method and control gets directly transfer to the calling
method
public class StackOverFlowReturn {
public static void main(String[] args) {
try {
System.out.println(display());
} catch (Exception ae) {
System.out.println("Arithmetic Exception");
}
}
static boolean display() {
try {
throw new ArithmeticException();
} catch (ArithmeticException e) {
throw e;
} finally {
System.out.println("finally");
}
}
}
Output:
finally
Arithmetic Exception
In catch block if you code return instead of explicit throw of
exception then
public class StackOverFlowReturn {
public static void main(String[] args) {
try {
System.out.println(display());
} catch (Exception ae) {
System.out.println("Arithmetic Exception");
}
}
static boolean display() {
try {
throw new ArithmeticException();
} catch (ArithmeticException e) {
return true;
} finally {
System.out.println("finally");
}
}
}
Output:
finally
true
You: If in the catch block I do not include a throw statement, the compilation fails again with the previous reason.
Answer: When you explicitly throw an exception in try block, then it
is not necessary to have an explicit throw in catch block. You can
code as follows:
public class StackOverFlowReturn {
public static void main(String[] args) {
System.out.println(display());
}
static boolean display() {
try {
throw new ArithmeticException();
} catch (ArithmeticException e) {
System.out.println("Arithmetic Exception");
} finally {
System.out.println("finally");
}
return true;
}
}
Output:
Arithmetic Exception
finally
true

Return from method, in the "try" block or after "catch" block?

Is there any difference between following two methods?
Which one is preferable and why?
Prg1:
public static boolean test() throws Exception {
try {
doSomething();
return true;
} catch (Exception e) {
throw new Exception("No!");
}
}
Prg2:
public static boolean test() throws Exception {
try {
doSomething();
} catch (Exception e) {
throw new Exception("No!");
}
return true;
}
Consider these cases where you're not returning a constant expression:
Case 1:
public static Val test() throws Exception {
try {
return doSomething();
} catch (Exception e) {
throw new Exception("No!");
}
// Unreachable code goes here
}
Case 2:
public static Val test() throws Exception {
Val toReturn = null;
try {
toReturn = doSomething();
} catch (Exception e) {
throw new Exception("No!");
}
return toReturn;
}
I would prefer the first one. The second is more verbose and might cause some confusion when debugging.
If test() incorrectly returns null, and you see toReturn being initialized to null, you might think the problem is in test() (especially when test() is not just a simple example like this).
Even though it can only return null if doSomething returns null. But that might be hard to see at a glance.
You could then argue that, for consistency's sake, it's better to always use the first form.
Nope there is no difference between both the methods.
It will return true value in both the cases effectively by resuming the flow of the program as soon an and exception is handled.
Catch will be accessed only when an exception occurs.
I'm assuming this is a general question. Otherwise I might comment on other aspects of your method(s).
I think in the case or small methods like these it doesn't really matter. The method is short enough to understand immediately what's going on, what's related to what etc.
However, in the case of longer methods the flow is much easier to follow in the first example. In my opinion. It keeps together related code and related scenarios. When you're reading the method, the normal execution flow is not broken by the catch block, making it more obvious and "fluent".
public static boolean test() throws Exception {
try {
doSomething();
return true;
} catch (Exception e) {
throw new Exception("No!");
}
}
But I won't generalize this for all methods; it's all about the context.
There is no difference, but the first Prg1 is faster than the Prg2.

Implementation of Finally Block

In the Code written below although i have not caught the ArithmeticException,yet the exception is handled automatically and with finally Block, the content of main() method is successfully Executed. Whereas if i remove the return statement from finally and make demo as returning void then the program after executing finally block throws MainThread Exception..why is it so?
public class FinallyDemo {
int demo() {
try {
int a=5/0;
}
finally {
System.out.println("Finally Executed");
return 10;
}
}
public static void main(String s[]) {
int a=new FinallyDemo().demo();
System.out.println("Exception Handled");
}
}
Because you return from the finally block, the exception is silently disposed. You should never return from a finally block! (Well, almost always never).
From the Java Language Specification:
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
This also means if you threw a different exception, like an IllegalStateException, from the finally block, the original exception would also be discarded.

Continue from the next line after getting exception

I want to continue with the next line from which error generated,
try{
statement A;
statement B;
statement C;
}
catch(NullPointerException NPE){.....}
Now assume that my statement A throws exception so I want to skip that and continue with B. Don't give my suggestion to put in catch/finally block or any other solution. I just want to know is this possible to skip and continue with next statement?
Yes, it is possible without the finally block.
try{
statement A;
}
catch(NullPointerException NPE){.....}
try{
statement B;
}
catch(NullPointerException NPE){.....}
try{
statement C;
}
catch(NullPointerException NPE){.....}
On the side note, I don't really think this is nice. If you managed to come to the point where you need this kind of flow control, you need to take a step back and rethink your code design.
It is not possible to execute statement B if A throws exception. One way is seperately try/catch block and other way is put other lines into finally block.
If your statements are similar and can be paramerized, use a loop:
for (int i = 0; i < statementCount; i++) {
try {
/** do what you need */
} catch(Exception e) {
}
}
or put it in separate method if it needs more parameters:
public static void main(String[] args) {
for (int i = 0; i < statementCount; i++) {
}
execute(params);
}
public void execute(Object... objects) {
try {
doSomthing(objects[0], objects[1]);
} catch(Exception e) {
}
}
If statements are abolutely different, Java 8 provides interesting solutions: method references and lambdas. So you can play arround with somthing like this:
public static void main(String[] args) {
execute(someObject, YourClass::method);
}
public void execute(Object param, Function<Object, Void> function) {
try {
function.apply(param);
} catch(Exception e) {
}
}
Like darijan already mentioned you could put every single statement into an own try-catch. Or if you know what may cause the exception you can simply check it befor you execute your statements
try{
if(parameterForStatementA != null) {
statementA;
}
if(parameterForStatementB != null) {
statementB;
}
if(parameterForStatementC != null) {
statementC;
}
} catch(Exception e) {
// something unexpected happened
}
Verifying parameters is usually more efficient than catching thrown exceptions

return statement and exception in try block in java

public class Test2 {
public static void main(String args[]) {
System.out.println(method());
}
public static int method() {
try {
throw new Exception();
return 1;
} catch (Exception e) {
return 2;
} finally {
return 3;
}
}
}
in this problem try block has return statement and throws exception also...
its output is COMPILER ERROR....
we know that finally block overrides the return or exception statement in try/catch block...
but this problem has both in try block...
why the output is error ?
Because your return statement is unreachable - the execution flow can never reach that line.
If the throw statement was in an if-clause, then the return would be potentially reachable and the error would be gone. But in this case it doesn't make sense to have return there.
Another important note - avoid returning from the finally clause. Eclipse compiler, for example, shows a warning about a return statement in the finally clause.
The compiler exception come from, like my Eclipse dude says
Unreachable code Test2.java line 11 Java Problem
The return statement of your main code block will never be reached, as an exception is thrown before.
Alos notice the return statement of your finally block is, at least, a design flaw, like Eclipse once again says
finally block does not complete normally Test2.javajava line 14 Java Problem
Indeed, as a finally block is only here to provide some clean closing, it is not expected to return something that would override the result normally returned by the method.
The throw new Exception() will be called no matter what, so anything within the try block that follows the throw is Unreachable Code. Hence the Error.
public class Test2 {
public static void main(String args[]) {
System.out.println(method());
}
public static int method() {
try {
throw new Exception();
return 1; //<<< This is unreachable
} catch (Exception e) {
return 2;
} finally {
return 3;
}
}
}
It should eventually return 3.
Because 'return' keyword within try block is unreachable, that's why you are getting compile-time error. Omit that 'return' keyword from try block, and then run your program, your will successfully compile.

Categories