0
class Demo{
public static void main(String args[]){
    int x=3,n=5,d=0;
    int ar[]=new int[3];
    String name="Neno";

    System.out.println("Start main");
    try{
        ar[x]=name.charAt(n)/d; //n=5
    }catch(StringIndexOutOfBoundsException e){
        System.out.println("String index Error");
    }catch(RuntimeException e){
        System.out.println("Any runtime Error");
    }catch(ArrayIndexOutOfBoundsException e){
        System.out.println("Array index Error");
    }catch(ArithmeticException e){
        System.out.println("Arithmetic Error");
    }

    System.out.println("End   main");
}
}

I used this code to filter some exceptions,but there is an error in the code. It says to remove the catch-clauses of ArrayIndexOutOfBounds and ArithmeticException. Is it because the order of the catch-clauses the error springs up? When I change the order like this...

class Demo{
public static void main(String args[]){
    int x=3,n=5,d=0;
    int ar[]=new int[3];
    String name="Niroth";

    System.out.println("Start main");
    try{
        ar[x]=name.charAt(n)/d; //n=5
    }catch(StringIndexOutOfBoundsException e){
        System.out.println("String index Error");
    }catch(ArrayIndexOutOfBoundsException e){
        System.out.println("Array index Error");
    }catch(ArithmeticException e){
        System.out.println("Arithmetic Error");
    }catch(RuntimeException e){
        System.out.println("Any runtime Error");
    }catch(Exception e){
        System.out.println("Any Error");
    }

    System.out.println("End   main");
}
}

There was no error in this order. Can anyone explain me the reason for this issue?

Rune Aamodt
  • 2,551
  • 2
  • 23
  • 27
Vbabey
  • 113
  • 1
  • 2
  • 10

7 Answers7

5

Catching exceptions is like buckets placed one after another.You must cacth broader ones in the last. Hope the following diagram helps:

Wrong:

 \                           /
  \_____RuntimeException____/

      \                  /
       \__AIOBException_/        //ArrayIndexOutOfBounds

      \                 /
       \__AriException_/        //ArithmeticException

Correct:

      \                  /
       \__AIOBException_/        //ArrayIndexOutOfBounds

      \                 /
       \__AriException_/        //ArithmeticException 

 \                           /
  \_____RuntimeException____/
rocketboy
  • 9,573
  • 2
  • 34
  • 36
4

You must catch specific exceptions before their superclasses (more broader exceptions, ie RuntimeException and Exception)

See here for the same question/answer: Order of catching exceptions in Java

Community
  • 1
  • 1
Kon
  • 10,702
  • 6
  • 41
  • 58
  • Yes It is a good explaination. But is there any other way we have to consider when considering the order of multi catch clauses? – Vbabey Aug 16 '13 at 07:42
  • As far as I know, in terms of the ORDER of catching, the only rules are that specific exceptions must be written first. My link goes into a little more detail. – Kon Aug 16 '13 at 07:44
1

Yes the order of catch clause matters

This is my logical explanation.

When you have

catch(Exception e){
   System.out.println("Any Error");
}
catch(RuntimeException e){
   System.out.println("Any runtime Error");
}

you can imagine that every an exception occurs, it is caught in Exception clause, the other block RuntimeException will never be reached/used.

Abubakkar
  • 15,488
  • 8
  • 55
  • 83
1

Both ArithmeticException, ArrayIndexOutOfBoundsException and StringIndexOutOfBoundsException extend RuntimeException (the last two via IndexOutOfBoundsException) - so in your first code snippet, the ArrayIndexOutOfBoundsException catch won't ever be reached.

You should always catch the most specific exceptions first and finish off with the least specific, as you do in the second code snippet.

Cheers,

Anders R. Bystrup
  • 15,729
  • 10
  • 59
  • 55
1

Yes, order matters. The first catch clause matching the exception will be executed, and the rest ignored.

As a side note, generally you should not catch RuntimeException. RuntimeException most likely means your logic is wrong or you're not doing the proper checkings.

m0skit0
  • 25,268
  • 11
  • 79
  • 127
0

You need to order the exceptions from most specific to least specific.

In your first example RuntimeException is somewhere in the middle of the catch blocks before ArrayIndexOutOfBoundsException and ArithmeticException, which are both RuntimeExceptions.

That means the catch block for the ArrayIndexOutOfBoundsException or ArithmeticException will never be reached since they extend RuntimeException whose catch block will handle the exception.

By ordering the exceptions from last specific to most specific (according to the class hierarchy) you give every exception a shot at resolving the exception.

Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
0

Exceptions should be caught from more specific to generalized. In other words, catch an exception of subclass before its superclass.

try
{
int e=33/0;
}

catch(ArithmeticException e)
{
//code here
}

catch (Exception e)
{
}
Malwaregeek
  • 2,274
  • 3
  • 15
  • 18