I'm reviewing some new code. The program has a try and a finally block only. Since the catch block is excluded, how does the try block work if it encounters an exception or anything throwable? Does it just go directly to the finally block?
If any of the code in the try block can throw a checked exception, it has to appear in the throws clause of the method signature. If an unchecked exception is thrown, it's bubbled out of the method.
The finally block is always executed, whether an exception is thrown or not.
A small note on try/finally: The finally will always execute unless
System.exit() is called.
The JVM crashes.
The try{} block never ends (e.g. endless loop).
The Java Language Specification(1) describes how try-catch-finally is executed.
Having no catch is equivalent to not having a catch able to catch the given Throwable.
If execution of the try block completes abruptly because of a throw of a value V, then there is a choice:
If the run-time type of V is assignable to the parameter of any catch clause of the try statement, then …
…
If the run-time type of V is not assignable to the parameter of any catch clause of the try statement, then the finally block is executed. Then there is a choice:
If the finally block completes normally, then the try statement completes abruptly because of a throw of the value V.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and the throw of value V is discarded and forgotten).
(1) Execution of try-catch-finally
The inner finally is executed prior to throwing the exception to the outer block.
public class TryCatchFinally {
public static void main(String[] args) throws Exception {
try{
System.out.println('A');
try{
System.out.println('B');
throw new Exception("threw exception in B");
}
finally
{
System.out.println('X');
}
//any code here in the first try block
//is unreachable if an exception occurs in the second try block
}
catch(Exception e)
{
System.out.println('Y');
}
finally
{
System.out.println('Z');
}
}
}
Results in
A
B
X
Y
Z
The finally block is always run after the try block ends, whether try ends normally or abnormally due to an exception, er, throwable.
If an exception is thrown by any of the code within the try block, then the current method simply re-throws (or continues to throw) the same exception (after running the finally block).
If the finally block throws an exception / error / throwable, and there is already a pending throwable, it gets ugly. Quite frankly, I forget exactly what happens (so much for my certification years ago). I think both throwables get linked together, but there is some special voodoo you have to do (i.e. - a method call I would have to look up) to get the original problem before the "finally" barfed, er, threw up.
Incidentally, try/finally is a pretty common thing to do for resource management, since java has no destructors.
E.g. -
r = new LeakyThing();
try { useResource( r); }
finally { r.release(); } // close, destroy, etc
"Finally", one more tip: if you do bother to put in a catch, either catch specific (expected) throwable subclasses, or just catch "Throwable", not "Exception", for a general catch-all error trap. Too many problems, such as reflection goofs, throw "Errors", rather than "Exceptions", and those will slip right by any "catch all" coded as:
catch ( Exception e) ... // doesn't really catch *all*, eh?
do this instead:
catch ( Throwable t) ...
Java versions before version 7 allow for these three combinations of try-catch-finally...
try - catch
try - catch - finally
try - finally
finally block will be always executed no matter of what's going on in the try or/and catch block. so if there is no catch block, the exception won't be handled here.
However, you will still need an exception handler somewhere in your code - unless you want your application to crash completely of course. It depends on the architecture of your application exactly where that handler is.
Java try block must be followed by either catch or finally block.
For each try block there can be zero or more catch blocks, but only one finally block.
The finally block will not be executed if program exits(either by calling System.exit() or by causing a fatal error that causes the process to abort).
how does the try block work if it
encounters an exception or anything
throwable
The exception is thrown out of the block, just as in any other case where it's not caught.
The finally block is executed regardless of how the try block is exited -- regardless whether there are any catches at all, regardless of whether there is a matching catch.
The catch blocks and the finally are orthogonal parts of the try block. You can have either or both. With Java 7, you'll be able to have neither!
Don't you try it with that program? It'll goto finally block and executing the finally block, but, the exception won't be handled. But, that exception can be overruled in the finally block!
The finally block is executed after the try block completes. If something is thrown inside the try block when it leaves the finally block is executed.
Inside try block we write codes that can throw an exception.
The catch block is where we handle the exception.
The finally block is always executed no matter whether exception occurs or not.
Now if we have try-finally block instead of try-catch-finally block then the exception will not be handled and after the try block instead of control going to catch block it will go to finally block.
We can use try-finally block when we want to do nothing with the exception.
Regardless of exception thrown or not in try block - finally block will be executed. Exception would not be caught.
Related
I have this code:
try {
// if (false) { //(need to add this, otherwise it doesn't compile)
// throw new CountDownExc(-1);
// }
return ad2;
} catch (StackOverflowExc | NoClassDefFoundError e) {
throw new CountDownExc(50);
} catch (CountDownExc e) {
if (!e.surfaced()) {
e.dec();
throw e;
}
return 0.0;
}
And if I don't add the commented code it doesn't compile with a:
error: exception CountDownExc is never thrown in body of corresponding
try statement
Why?
Most of all, why does the first catch doesn't cause the compiler to complain (but the second block seems to be wrong)
There is a couple of problems with your code:
First and foremost you need to understand the difference between checked exceptions and unchecked exceptions: Understanding checked vs unchecked exceptions in Java
Essentially you need to consider checked exceptions as part of your logic and you can only either rethrow them or handle them via catch. The only other option if you need to avoid catch( CountDownExc ) is to add a throws CountDownExc declaration to your method.
These lines make little sense to me:
} catch (StackOverflowExc | NoClassDefFoundError e) {
throw new CountDownExc(50);
It looks like you intend on catching two exception types in the first catch block, throw CountDownExc in that first catch block, then handle it in the second catch block. That's not gonna fly, because catch blocks handle what is thrown in a try block, not in a catch block. Since CountDownExc is a checked exception this is going to result in another compilation error, unless you either wrap your try-catch in another try-catch (bad practice) or add a throws declaration.
See: Exception thrown inside catch block - will it be caught again?
Since both of your catches throw CountDownExc the exception will have to be handled elsewhere anyway, so this may already be accounted for - I cannot tell, because the rest of your code is unknown.
Your immediate problem however comes from the fact, that nothing in your try block is able to throw CountDownExc and CountDownExc is a checked exception, see first link.
I am new to Java. I was going through the Exception Handling Concept but I stuck at one point here.
We know that whenever the Exception is thrown Java will try to find by looking at the available catch clauses in the top down manner. If it doesn't find one, it will search for a handler for a supertype of the Exception.If it does not find a catch clause that matches a supertype for the exception, then the exception is propagated down the call stack.
Also if most specific exceptions is placed above the more general exceptions handler then it results in the COmpilation error.
Suppose we have a code as shown below:-
try{
// do not know what kind of exception it will be throwing but I am sure that it is IOException
}
try{
// Here the FileNotFoundException is thrown
}
catch(IOException e){
//Do exception handling stuff
}
catch(FileNotFoundException f){
//Do exception handling stuff`
}
Now this code will result in the compilation error because the Supertype of the exception is present above the actual exception.
SO why the first paragraph do not support this concept. i.e After checking JVM will found the appropriate exception(FileNotFoundException) and should not bother about IOException clause, but run into compilation error instead.
Please throw some light on it.
Also let me know If I am able to explain what I want to??
It looks like you are misunderstanding the try concept. You only have one try followed by the catch clauses.
try{
// do not know what kind of exception it will be throwing but I am sure that it is IOException
// Here the FileNotFoundException is thrown
}
catch(IOException e){
//Do exception handling stuff
}
catch(FileNotFoundException f){
//Do exception handling stuff`
}
This code will throw an error at compile time because for FileNotFound Catch Block the code will be unreachable as it's already handled by IO Exception and FileNotFound is subclass for IOException
Unreachable catch block for FileNotFoundException. It is already handled by the catch block for IOException
FileNotFoundException is a subclass of IOException gives us the choice of either treating all IOExceptions the same, or catch some of IOExceptions subclasses individually
Code snippet has fundamental mistakes
If an exception occurs within the try block, that exception is handled by an exception handler associated with it. To associate an exception handler with a try block, you must put a catch block after it
Recommended reading:
https://docs.oracle.com/javase/tutorial/essential/exceptions/try.html
https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html
try
{
throw tryException();
}
catch
{
throw catchException();
}
finally
{
throw finallyException();
}
According to the official Java Documentation:
"The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs."
See https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html
The finally exception will be thrown except under the condition Suresh Atta has stated in the comments; System.exit() is called, which will abruptly terminate the program.
Remember in the absence of System.exit(), the finally block always runs after the catch block.
As the finally block is ran last, the exception thrown in the finally block will be thrown.
N.B: You can have try, finally block without a catch block.
How much better is:
if (condition) {
try {
//something
} catch(SomeEx ex) {}
}
instead of this:
try {
if (condition) {
//something
}
} catch(SomeEx ex) {}
What actually JVM do when I enter try block ?
EDIT:
I don't want to know that in second example always go in to try... Please answer the question.
Execution wise at run time, as long as there is no exception, try does not cost you anything. It only costs run time as soon as an exception occurs. And in that situation it is much slower that an if evaluation.
In the JVM spec, you see that there is no extra byte code generated on the execution path:
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-3.html#jvms-3.12
try {if (condition) {...}} catch(SomeEx ex) {}
Here you handled the exception if it is arised condition of if also if arised inside if-block.
if (condition) {try {...} catch(SomeEx ex) {}}
Here you handle exception if is arised only inside the if-block. If something goes wrong in if condition then it will not be handled.
So it is depends upon the actual senario.
From the perfomance point of view it should be the same. Throwing of the exception is a costly operation (for starters, the stacktrace must be created and populated). The mere existence of the try block has no (or negligible) performance penalty.
See Should java try blocks be scoped as tightly as possible.
What actually JVM do when I enter try block ?
From JLS 14.20.1. Execution of try-catch:
A try statement without a finally block is executed by first executing the try block. Then there is a choice:
If execution of the try block completes normally, then no further action is taken and the try statement completes normally.
If execution of the try block completes abruptly because of a throw of a value V, then there is a choice:
If the run-time type of V is assignment compatible with (§5.2) a catchable exception class of any catch clause of the try statement, then the first (leftmost) such catch clause is selected. The value V is assigned to the parameter of the selected catch clause, and the Block of that catch clause is executed, and then there is a choice:
If that block completes normally, then the try statement completes normally.
If that block completes abruptly for any reason, then the try statement completes abruptly for the same reason.
If the run-time type of V is not assignment compatible with a catchable exception class of any catch clause of the try statement, then the try statement completes abruptly because of a throw of the value V.
If execution of the try block completes abruptly for any other reason, then the try statement completes abruptly for the same reason.
EDIT:
For a complete Exception description see the JVM 2.10 link in The New Idiot's answer.
If you see oracle docs
>try {
code
}
catch and finally blocks . . .
The segment in the example labeled code contains one or more legal lines of code that could throw an exception.
So,If you feel doubt on your If condition that it will throw an exception put it inside.Otherwise put outside.
if (condition) {
try {
//something
} catch(SomeEx ex) {}
}
is better to use since it executes the try block if the condition is ok.JVM compiles the try block and validated the catch block or a finally block. I think advantage is not in the compile time but in the run time. Compile time I think no advantage at all
Exceptions should be exceptional case , not every time the code runs. So better to check for the condition before trying !
if (condition) {
try {
//something
} catch(SomeEx ex) {}
}
Make sure , if (condition) itself doesn't throws an Exception.
It depends on your usage and functionality . For example this would be better :
if (someObject!=null) {
try {
someObject.getSomething(); // getSomething() potentially throws some Exception
} catch(SomeEx ex) {}
}
What actually JVM do when I enter try block ?
Read JVM spec 2.10.
If I run the following code:
try{
return false;
} catch(Exception e){
e.printStackTrace();
}
finally{
return true;
}
why does it return true?
From the Java Language Specification section 14.20.2
If execution of the try block completes abruptly for any other reason R, then the finally block is executed, and then there is a choice:
If the finally block completes normally, then the try statement completes abruptly for reason R.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
(my italics). A return is one kind of "abrupt completion", in other words the return from the finally overrules the one from inside the try.
It returns true because whenever a finally block completes abruptly, either by return-ing or by throwing an exception, that completion supersedes any previous return-value or exception. (See §14.20.2 "Execution of try-finally and try-catch-finally" in the Java Language Specification, Java SE 7 Edition.)
Because no matter what happens in the try catch portion, the finally block will always do what you ask so in this case it returns true. Just remove the finally statement and it should return false.
Finally block doesnot execute when try or catch block terminate by calling System.exit function. Similarly if the thread executing try catch dies while executing try or catch block then finally block may not execute.
So its likely that your try catch finally block will almost always return true even if your try block is returning false .
Because the finally block will always be executed if a return is encountered.