1

Below is the code that I was trying to understand.

public static void main(String[] args)
{
    try
    {
        System.out.println(args[0]);
    }
    catch (ArrayIndexOutOfBoundsException e)
    {
        System.out.println("ArrayIndexOutOfBoundsException");
        throw new NullPointerException();
    }
    catch (NullPointerException e)
    {
        System.out.println("NullPointerException");
        throw new Exception();
    }
    catch (Exception e)
    {
        System.out.println("Exception");
    }
}

Everything is fine except when I am throwing new Exception();. So when I am doing so an error is occurring saying, "Unhandled exception type Exception" though I have provided the catch statement below to handle it.

So I know the solution to the problem but I want to know the reason. What are the insights that I am missing.

Can anybody explain it.

Varun Jain
  • 1,371
  • 12
  • 26

1 Answers1

4

though I have provided the catch statement below to handle it.

A catch block only handles exceptions in the corresponding try block. Your throw new Exception(); statement is in a catch block instead - and likewise you're currently throwing NullPointerException from a catch block, and that won't be caught by the catch block below it. The compiler knows that the catch (Exception e) block does not handle the exception thrown in the catch (NullPointerException e) block, and therefore it gives you a compile-time error just as if you had that throw statement without any try/catch at all.

If you change your code to:

try
{
    System.out.println(args[0]);
    throw new Exception();
}
catch (ArrayIndexOutOfBoundsException e)
{
    System.out.println("ArrayIndexOutOfBoundsException");
}
catch (NullPointerException e)
{
    System.out.println("NullPointerException");
}
catch (Exception e)
{
    System.out.println("Exception");
}

... then it should compile and be fine.

If you want to handle exceptions thrown from a catch block, then you'll need nested try blocks. For example:

try
{
    try
    {
        System.out.println(args[0]);
    }
    catch (ArrayIndexOutOfBoundsException e)
    {
        System.out.println("ArrayIndexOutOfBoundsException");
        throw new NullPointerException();
    }
    catch (NullPointerException e)
    {
        System.out.println("NullPointerException");
        throw new Exception();
    }
}
catch (Exception e)
{
    System.out.println("Exception");
}

Now, consider what happens if you run this with no command line arguments:

  • The inner try block will throw ArrayIndexOutOfBoundsException
  • The first catch block will catch the exception, print a message to the console, and then throw NullPointerException
  • The final catch block will catch the NullPointerException and print just "Exception" to the console. Importantly, the catch (NullPointerException e) block will not catch that exception, because the exception wasn't thrown from the try block that it's associated with

Note that having nested try/catch blocks like this is relatively rarely a good idea. It's fine in terms of trying to understand how exceptions work in Java, but not a good idea in real code. (Likewise catching ArrayIndexOutOfBoundsException and NullPointerException is rarely a good idea in real code.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    @VarunJain: Then you need that `catch` block to be inside a `try` block. I'll edit my answer to show how that would work - but I definitely *do* understand the problem itself. I may not know exactly what you're trying to achieve, but that's a different matter... (You only said you were trying to *understand* the code, which is why I've *explained* it.) – Jon Skeet May 16 '19 at 13:30
  • 1
    Really sorry for the language. Didn't do it to insult anybody here. – Varun Jain May 16 '19 at 13:56