• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Exception handling: Statements after the finally block

 
Ranch Hand
Posts: 204
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Hi,
I am getting confused about when the statements after finally method will be executed and when not.
could anyone please explain or could tell me a site where i can get a good explanation
thanx in advance
Neha

 
Ranch Hand
Posts: 97
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Neha,
I'll give it a go...
This is what I think will happen based on the following structure.
~~~
try{
//statements
}
catch{
//statements
}
finally{
//statements, possibly including another try/catch
}
//more statements here
~~~

The statements after finally will execute if
a). no exception was produced within the try block or within the finally block.
or
b). an exception was produced within try or finally, but was caught
The statements after finally won't execute if an uncaught exception is produced within try or finally.

If an exception occurs within the try block, statements in the finally block will execute regardless of whether the exception is caught. The finally block is always executed regardless of how the try block is exited (eg. via return, break, continue, or just by reaching the end of the try block). It's meant to be a guaranteed way to clean up before exiting a method.

If an exception occurs within the try block and is not caught, finally will still execute, but the statements following finally will not execute.
If try has not produced an uncaught exception but if the finally block produces an uncaught exception, the code following the finally block will not execute.
If no exception occurs prior to the statements following finally, they will execute (following execution of the statements within the finally block).
I don't know of a website, but here's a concise summary from one of my text books of terms used in exception handling
try
~~~
This defines a block of statements that may throw an exception. If an exception is thrown, an optional catch block can handle specific exceptions thrown within the try block. Also, an optional finally block will be executed regardless of whether an exception is thrown or not.
catch
~~~
This is used to declare a block of statements to be executed in the event that an exception, or a run-time error occurs in a preceeding try block.
throw
~~~
This allows the user to throw an exception or any class that implements the throwable interface.
throws
~~~
This keyword is used in method declarations that specify which exceptions are not handled within the method, but rather passed to the next higher level of the program.
finally
~~~
This executes a block of statements regardless or whether an exception or a run-time error occurred in a block defined previously by the try keyword
cheerio
rowan

 
Neha Sawant
Ranch Hand
Posts: 204
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thank you Rowan.
Wonderful explanation.
Cleared few of my doubts.
One more question.
If you declare that a method throws a particular excetion and we explicitly throw a subclass of that exception using throw
It sometimes gives an error saying that throws clause declares one exception and you are throwing another exception.
Could you please explain this part to me.
Does the throw exception has to be caught even if throws is defined.
Thanx in advance
Neha
 
Rowan Brownlee
Ranch Hand
Posts: 97
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Neha,
I don't know about this - haven't struck it myself. I hope someone can explain, as I'd be interested in finding out.
cheerio
rowan
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Neha
a throws clause should be valid for any subException of the ones declared in it. Can you post the code and the error that is not behaving like that?
 
Neha Sawant
Ranch Hand
Posts: 204
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thnanx Rowan and Jose
Jose, i do not have code right now but i remember i had come across a code like that.
As of now i will remember that throw should be a sobclass of the exception that is thrown in the throws clause.
I will post the code if i come across it again.
Thanx once again
Neha
 
Neha Sawant
Ranch Hand
Posts: 204
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Rowan,
i am back with a code.
Here exception is caught but it is still saying satment not reached.
Acc. to you the statements after finally will be executed if exception is caughtimport java.io.*;
public class Test027 {
public static void main(String args[]) {
System.out.println(method());
}
static int method() {
try { throw new IOException();
}
catch (IOException ioe) {
System.out.println("0");
return 0;
}
finally {
System.out.println("1");
return 1;
}
return 2;
}
}

 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
"return 1" is to blame. The same as an uncaught exception within finally prevents the statements after finally from being executed, return has the same effect.
The compiler complains because it sees an instruction after a return.
Think of finally as a little subroutine that gets called before an instruction tries to leave the try/catches clauses set (case a). Also it gets called when no such thing happens and the try/catches code simply completes via a right bracket "}" (case b).
The compiler places a bytecode at the end of the finally code that jumps back the next instruction where the jump to finally took place, when this bytecode is reached controll returns exactly to point where it had jumped to the finally clause. In this way a finally clause really is a subroutine. The problem is if there is an instruction that prevents the execution of the returning jump at the end of finally. Any uncaughth exception, return, break or continue within finally does that.
Case a:
A return, uncaught exception, continue or break tries to jump out the finally/catches clauses. Code in finally gets called before trying to execute the leaving instruction. If finally doesn't complete executing the returning jump instruction (that was at the end of fianlly clause, simply because a return, uncaught exception, break or continue withing finally was executed before it) control won't return to execute the leaving instruction that caused the jump to finally clause. Note that the returning addres of the jump is the one that provoked the initial call to finally.
Case b:
There is no such leaving instruction from the try/catches clauses set. If the code in finally is able to execute the returning jump, the returning address will be the next bytecode after the finally clause, because all the code in try/catches was effectively runned. However if there were such an instruction that jumped out of the finally code, depending where the destination was, the statement after finally will be executed or not. I mean obviously a return or uncaught exception will finish the current method.
hope helps
 
Neha Sawant
Ranch Hand
Posts: 204
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jose,
Thanx for your explanation.
Now if the return statement in finally is commented then it should compile properly and return 2 will be executed.
Am i right?
And if an exception was caught in catch clause and while executing finally an exception occurs then also the satements after finally will not be executed and compile time / runtime exception will be generated accordingly.
Please correct me if i am wrong
Thanx once again
Neha
 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Jose,
I have tried Test027.java. The compiler blames "return 2;" not "return 1;". Why?
If "return 2" is commented, the output is
0
1
1
It means that "return 0;" is not executed. Why?
Please help.
Thanks,
Dong
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Neha you are right
Hi Dong
I said return 1 is to blame because if you comment it out code compiles. Also you can consider return 1 the offending line because it is a line after a return. One of both should be left out.
Please read my explanation again. Before executing return 0 finally is executed. Because there is a return statement within finally, the jumping back instruction is not executed. So control can not returned back to execute return 0.
hope helps
 
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi, there
my way of understanding this question is that:
finally block is always executed, so in this code example after executing the finally block the execution is returned by "return 1" back to the caller--method()(inside the System.out.println)it means it terminated the execution of callee(metho(){}). That is why "return 2" can not be reached. But,if inside the finally block there is not return clause the VM will search the return clause(why ? because this method need something return as indication of finishing) inside the method()body from the beginning.In this exapme, if comment "return 1", "return 0" will be executed rather than "return 2".
hope it helps
 
Neha Sawant
Ranch Hand
Posts: 204
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
Jose i had difficulty in this example.Here method declares that it throws Exception and in the throw clause it throws IllegalAccessException which is a subclass of Exception then it should be caught in main method and ans should have been D.
Please could u explian this to me

public class ThrowsDemo {
static void throwMethod() throws Exception {
System.out.println("Inside throwMethod.");
throw new IllegalAccessException("demo");
}
public static void main(String args[]) {
try {
throwMethod();
} catch (IllegalAccessException e) {
System.out.println("Caught " + e);
}
}
}
A) Compilation error
B) Runtime error
C) Compile successfully, nothing is printed.
D) inside throwMethod. followed by caught: java.lang.IllegalAccessException: demo

A) Compilation error
Explanation:
The method throwMethod() is throwing a type Exception class instance, while catching the exception you are catching the subclass of Exception class.
 
Neha Sawant
Ranch Hand
Posts: 204
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi,

Could anyone help me out with this question.
Thanx in advance
Neha
 
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Neha:
Inside throwMethod(), you are throwing IllegalAccessException.
It declares that it throws Exception (which is a super class of
IllegalAccessException).
A method can declare that it throws an exception even though it is not really throwing an exception. A method must declare the same exception actually thrown in its body or it must declare the superclass of the thrown exception.
Since throwMethod() throws the superclass of the originally thrown exception in its body, it does not have any problem.
So, option D can not be answer as there is no problem inside the method throwMethod().
Now, let us consider the caller of the throwMethod(). Since the
throwMethod declares that it throws Exception, the caller of the method must catch the same exception or super class of that exception or it must declare that it is also throwing the same exception (or super class of that exception), in which case the responsibilty of handling the exception is explicitly passed to the caller of this method.
In your program, the caller of the throwMethod() violates this rule. It is catching only the subclass of the exception originally thrown by throwMethod(). So, it is a compiler error.So, option A is the answer.
Hope this helps...
Uma
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
to Neha
The compiler is responsible for checking that the ckecked exceptions are either caught or declared. But the compiler just checks the types declared in throws clause (if there is such throws). It doesn't figure out the runtime type of the thrown exception. Just realize that the error message given by the compiler mentions Exception, not IllegalAccessException. I don't know if this is because the compiler is not able to figure out the runtime type of a thrown exception or just to speed things.
Now if the compiler thinks an Exception is thrown, an Exception must be caugth. However within the catch clause the runtime type of the exception can be discovered.
Also
JLS 14.17 says:
"
The Expression in a throw statement must denote a variable or value of a reference type which is assignable (�5.2) to the type Throwable , or a compile-time error occurs. Moreover, at least one of the following three conditions must be true, or a compile-time error occurs:
*
*
* The throw statement is contained in a method or constructor declaration and the type of the Expression is assignable (�5.2) to at least one type listed in the throws clause (�8.4.4, �8.8.4) of the declaration.
"
So maybe throws performs an assignment convertion of the declared type of the thrown exception to the type declared in throws.
Anyway the morale of the story is that you must catch the checked types declared in throws not those really thrown.
 
Uma Viswanathan
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Neha:
I understood wrongly that option D as an error inside the throwMethod(). I understand now that it is actually the output if the program runs successfully. Anyways, it can not be answer bcoz the program will not run successfully due to compilation error.
Check this out...
static void throwMethod() throws IllegalAccessException {
System.out.println("Inside throwMethod.");
throw new Exception("demo");
}
We will get compiler error bcoz Exception must be caught or must be declared in the method. As Jose had written, assignment conversion of Exception to IllegalAccessException is not possible...
Uma
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Also interesting:
public void method() throws IllegalAccessException {
(Exception) throw new IllegalAccessException();
}
This won't compile because the declared type of the thrown exception is not assignable compatible with the type declared in throws. I mean the compiler only sees that the type Exception is not the same or a subclass of IllegalAccessException. Compiler doesn't sees the runtime type of the thrown object.
 
Neha Sawant
Ranch Hand
Posts: 204
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thanx Uma and Jose,
if my example is like this ,then they will be know problem.
I am trying to understand this as i get confused in this.
Correct me if i am wrong.

public class ThrowsDemo {
static void throwMethod() throws IllegalAccessException {
System.out.println("Inside throwMethod.");
throw new IllegalAccessException("demo");
}
public static void main(String args[]) {
try {
throwMethod();
} catch (Exception e) {
System.out.println("Caught " + e);
}
}
}

now since Exception is super class of IllegalAccessException it will be caught.

 
Uma Viswanathan
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Neha:
This is absolutely correct.
Uma
 
Uma Viswanathan
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jose:
I am getting compiler error "invalid expression statement" at the line
(Exception) throw new IllegalAccessException();
Is it possible to type cast like the way you told...? Please do give explanations...
Uma
 
Uma Viswanathan
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
We can type cast like this...
throw ((Exception)new IllegalAccessException());
 
Neha Sawant
Ranch Hand
Posts: 204
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


public class ThrowsDemo {
static void throwMethod() {
System.out.println("Inside throwMethod.");
throw new IllegalAccessException("demo");
}
public static void main(String args[]) {
try {
throwMethod();
} catch (IllegalAccessException e) {
System.out.println("Caught " + e);
}
}
}
will give compiler error as the method throwing an exception should either catch it or declare it in the method declaration
correct me if i am wrong
regards
neha
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Neha, Uma is right. I just compiled the right sentence and posted the wrong one.
Have you tried the code? have you read a very interestring post by Val titled GENERAL COMMENTS?
 
Neha Sawant
Ranch Hand
Posts: 204
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yes Jose i have compiled and i have got this error but according to your explaination i thought that it should compile but it did not and so i wanted to know what's happening.
I am still getting confused.
Can u suggest some good material from where i can get a good understanding of this.
Regards
neha
 
Sheriff
Posts: 9109
12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
http://java.sun.com/docs/books/tutorial/essential/exceptions/index.html
 
Neha Sawant
Ranch Hand
Posts: 204
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thankyou Marilyn
i am getting a rough idea of what's happening
regards
neha
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic