class chain_exceptions{
public static void main(String args[]){
try
{
f1();
}
catch(IndexOutOfBoundsException e)
{
System.out.println("A");
throw new NullPointerException(); //Line 0
}
catch(NullPointerException e) //Line 1
{
System.out.println("B");
return;
}
catch (Exception e)
{
System.out.println("C");
}
finally
{
System.out.println("D");
}
System.out.println("E");
}
static void f1(){
System.out.println("Start...");
throw new IndexOutOfBoundsException( "parameter" );
}
}
I expected the Line 1 to catch the NullPointerException thrown from the Line 0 but it does not happen.
But why so ?.
When there is another catch block defined, why cant the NPE handler at Line1 catch it ?
Is it because the "throw" goes directly to the main() method ?
Catch{ . . . } blocks are associated with try{ . . . } blocks. A catch block can catch exceptions that are thrown from a try block only. The other catch blocks after first catch block are not associated with a try block and hence when you throw an exception, they are not caught. Or main() does not catch exceptions.
A kind of this for each catch block will do what you are trying to do.
try{
try
{
f1();
}
catch(IndexOutOfBoundsException e)
{
System.out.println("A");
throw new NullPointerException(); //Line 0
}
}
catch(NullPointerException e) //Line 1
{
System.out.println("B");
return;
}
The catch blocks are only for the try block. They won't catch exceptions from other catch blocks.
catch statements only catch exceptions thrown from a try { ... } block.
The NullPointerException is thrown from a catch { ... } block, not a try { ... } block.
To catch an exception thrown from a catch block you need to put another try block inside of it. Outside, wrapping the original try...catch would work, too.
A second catch doesn't catch the exception from the first catch block. You have to add another try-catch within the first catch block (or around the whole try-catch you already have) to make this run as expected.
Since java 7 you can use code below or an other option is to nest the try catch statements, there is no other option in java
try {
...
} catch( indexoutofboundsexception| nullpointerexception ex ) {
logger.log(ex);
throw ex;
}
Your catch clauses only catch exceptions thrown by f1(). They don't call exceptions thrown in other catch clauses of the same try-catch-finally construct.
Because f1() throws IndexOutOfBoundsException.
try
{
f1(); //throws IndexOutOfBoundsException
}
catch(IndexOutOfBoundsException e) //gets caught here immediately and does not check other catch blocks
{
System.out.println("A");
throw new NullPointerException(); //Line 0
}
Short answer: yes, the throw will directly throw the exception to the main method.
Generally, once a catch block is executed, it behaves like an else if, that is, it won't consider the other alternatives.
No, the reason it isn't being caught is because it isn't in the try block which is linked to the catch block. If you want to catch that exception as well, you would have to wrap the throw in a new try/catch group. The reason why you would want to do this tho, is a riddle to me.
What you also can do btw:
catch (IndexOutOfBoundsException|NullPointerException e)
This will also allow you to use the same catch block for multiple types of exceptions.
Your expectation was incorrect:
The catch blocks are associated with the try block. So once an exception is thrown inside of the try, it leaves that scope. Now you are in the scope outside the try, meaning you are no longer in any try/catch block. Any exceptions thrown here (when you re-throw) will not be caught by anything, and yes, bubble out of main.
You can not catch exception from another catch block, for that you probably need to do something like this, in your first catch block
System.out.println("A");
try{
throw new NullPointerException(); //Line 0
}
catch(NullPointerException e) //Line 1
{
System.out.println("B");
return;
}
Related
Here is my code:
public static void main(String[] args) {
System.out.print("a");
try {
System.out.print("b");
throw new IllegalArgumentException();
} catch (IllegalArgumentException e) {
System.out.print("c");
throw new RuntimeException("1");
} catch (RuntimeException e) {
System.out.print("d");
throw new RuntimeException("2");
} finally {
System.out.print("e");
throw new RuntimeException("3");
}
}
I can not understand why the output is abce and RuntimeException("3")
That becomes clear when you indent your code as it should be:
try {
System.out.print("b");
throw new IllegalArgumentException();
} catch (IllegalArgumentException e) {
System.out.print("c");
throw new RuntimeException("1");
} catch (RuntimeException e) {
System.out.print("d");
throw new RuntimeException("2");
} finally {
System.out.print("e");
throw new RuntimeException("3");
}
The point is: there is only one try block. And the first catch block is taken. That one throws - and this exception 1 would be the one you notice in your stacktrace.
But thing is: the finally block is throwing "on top" of exception 1. Therefore you see exception 3.
In other words: there is a misconception on your end. You probably assume that exception 1 should be caught by the second catch block. And that is wrong. The second catch block only covers the first try block. Meaning: an exception from a catch block does not result in another catch block being taken. The first catch block "fires", and the finally block "fires" - leading to the observed results.
While you can have many catch() blocks, a maximum of 1 catch() will be executed when an exception is thrown. After that it will execute finally block, hence you have the output abce and the RuntimeException from finally block.
It is because, after IllegalArgumentException thrown in try block, it is caught in corresponding catch (IllegalArgumentException e) { } block. As finally block gets executed regardless of exception, e get printed.
To your question, Since the exception was already caught in catch block it will throw the corresponding exception accordingly and it will get propagated to the caller of that method.
I've tried to throw the same excpetion in a finally block, while the previously throwed expcetion was not catched. I expected that we have two object of Excpetion type that shal be thrown. Since we need in two catch clauses as the following:
public static void main(String[] args) {
try {
try {
try {
throw new Exception();
} finally {
System.out.println("finally");
throw new Exception();
}
} catch (Exception ex) {
System.out.println("catch");
} finally {
System.out.println("finally");
}
} catch (Exception ex) {
System.out.println("catch");
}
System.out.println("finish");
}
But that program prints:
finally
catch
finally
finish
That is, the second catch clause was not entered. Why?
When you throw an exception in the finally block, the first exception silently disappears.
It's in the JLS Chapter 14.20.2
If the finally block completes abruptly for reason S, then the try
statement completes abruptly for reason S.
This is true how ever you entered the finally block. If you entered it by throwing an exception T that exception can not be catched anymore.
When you throw an exception from the finally block, it supresses any exception thrown from the try block, therefore there was only one exception to catch.
The first catch cluase already caught that exception, so the second one had nothing to catch.
Your first try-catch is already trying to catch it, the extra try blocks aren't there for any particular reason. If you try to throw more exceptions you'll notice that you'll get a syntax error, Unreachable code
Basically, keep it in one try block
I am implementing exception handling in java with multiple exceptions.
Look at the following scenario:
Function f1 throws Exceptions e1, e2, e3 and e4
and Function f2 catches these.
Now I want to catch e1,e2 explicitly by catch(Exception e1 and e2) and the other exceptions should be caught all in the same block by catch(Exception e)
So e1 and e2 are a special case, and others are all general exceptions.
So will the following work?
try{
//some work`
} catch(ExceptionType1 e1) {
//do some special logging
} catch (ExceptionType2 e2) {
//do some special logging
} catch(Exception e) {
//do general logging for other exceptions
}
My question is whether ExceptionType1(e1) will also be caught by Exception e?
The Spec writes:
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.
Therefore, at most one catch block will be executed.
For that to work you need to have catch blocks with different Exceptions
like NullPointerException NumberFormatException and the general exception will be caught by catch block with Exception parameter since Exception is the super class of all Exceptions
try{
//some work`
} catch(NullPointerException e1) {
//do some special logging
} catch (NumberFormatException e2) {
//do some special logging
} catch(Exception e) {
//do general logging for other exceptions
}
Using your code will catch all Exceptions in catch(Exception e1){...}
The other catch-blocks are unused. If you want to handle different Exception-types on different way you have to give the catch(...) other Exception-types.
Like
try{
}catch(IOException e1){
// Do sth
}
catch(NullPointerException e2){
// Do sth else
}
// and so on...
You cannot have multiple catch blocks with the same class i.e. Exception
If you have multiple Exceptions you need to create a separate class for each one and make your catch block for a specific class
Just be aware the order of your catch block must go from the more specific to the more generic class
e.g.
try {
} catch (FileNotFoundException e) {
System.err.println("FileNotFoundException: " + e.getMessage());
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
} catch (Exception e) {
System.err.println("Caught Exception: " + e.getMessage());
} catch (Throwable e) {
System.err.println("Caught Throwable: " + e.getMessage());
}
So in the above code if the exception is of FileNotFoundException only the first catch will be executed. Otherwise the catch block with Exception is going to be executed for any instance of Exception class that was not caught in the previous catch blocks
At the end Throwable will catch anything that does not inherent from Exception such as Error
I am trying to put a while loop inside a try /catch block. To my curiosity finally of that try catch is not executed when the while loop exits. Can some explain what is happening actually?
I tried to google, but cnould not find any details.
I assume your code looks like this:
try
{
while (...)
{
// ...
}
}
catch (FooException ex)
{
// This only executes if a FooException is thrown.
}
finally
{
// This executes whether or not there is an exception.
}
The catch block is only executed if there is an exception. The finally block usually executes whether or not an exception was thrown. So you will probably find that your finally block is actually being executed. You can prove this to yourself by placing a line there that causes some output to the console.
However there are situations in which the finally block doesn't run. See here for more details:
Does a finally block always run?
It can happen only if your program exits either by using System.exit() or if an Error or Throwable were thrown (vs. Exception that will be caught).
Try the following:
public static void main(String[] args) {
try{
System.out.println("START!");
int i=0;
while(true){
i++;
if(i > 10){
System.exit(1);
}
}
}
catch (Exception e) {
// TODO: handle exception
}
finally{
System.out.println("this will not be printed!");
}
}
I am using a try catch block to catch an exception. The console shows that it is throwing a null value. But it is not going to the catch block.
try {
System.out.println("Exception here "+SomeObject.getValue());
} catch (NullPointerException e) {
// TODO: handle exception
SomeObject so = new SomeObject();
}
SomeObject.setValue();
}
How could this be handled. Can I also use method level throws NullPointerException ?
It indeed would have went inside the catch block. There is another potential NullPointerException at the line (assuming you are trying to say)
so.setValue();
Having said that it is not advised to throw RuntimeException. It is better you handle NullPointerException in your code not through try/catch but through simple condition checks
it is a bad idea to catch UnChecked Exceptions, rather than catching NullPointerExcetpion, you can simple check for null values in an If condition.
if(SomeObject.getValue()!=null)
System.out.println(SomeObject.getValue());
You can put another try block inside catch
try {
doSomething();
} catch (IOException) {
try {
doSomething();
} catch (IOException e) {
throw new ApplicationException("Failed twice at doSomething" +
e.toString());
}
} catch (Exception e) {
}