4
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 ?

UnderDog
  • 3,173
  • 10
  • 32
  • 49
  • 1
    possible duplicate of [Exception thrown inside catch block - will it be caught again?](http://stackoverflow.com/questions/143622/exception-thrown-inside-catch-block-will-it-be-caught-again) – Aniket Kulkarni Sep 04 '13 at 07:52
  • You should read a bit about the [Java naming conventions](http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-135099.html#367). – sp00m Sep 04 '13 at 07:53
  • http://stackoverflow.com/questions/3779285/exception-thrown-in-catch-and-finally-clause – Aniket Kulkarni Sep 04 '13 at 07:53
  • In case you're curious, you can find the details in the Java specification [here](http://docs.oracle.com/javase/specs/jls/se7/html/jls-11.html#jls-11.3). – Ben Sep 04 '13 at 07:54
  • Exceptions are caught by a *nested* block, not a block at a the same level. – Peter Lawrey Sep 04 '13 at 08:01

11 Answers11

9

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;
}
sr01853
  • 6,043
  • 1
  • 19
  • 39
3

The catch blocks are only for the try block. They won't catch exceptions from other catch blocks.

tea2code
  • 1,007
  • 1
  • 8
  • 15
3

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.

Nicole
  • 32,841
  • 11
  • 75
  • 101
2

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.

Kai
  • 38,985
  • 14
  • 88
  • 103
2

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;
}
jonas vermeulen
  • 1,235
  • 5
  • 23
  • 40
1

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.

1

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
      }
Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
1

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.

justhalf
  • 8,960
  • 3
  • 47
  • 74
1

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.

MrP
  • 1,291
  • 1
  • 9
  • 18
1

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.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
1

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;
}
commit
  • 4,777
  • 15
  • 43
  • 70