1

JLS 8, 14.20:

A try statement executes a block. If a value is thrown and the try statement has one or more catch clauses that can catch it, then control will be transferred to the first such catch clause.

It looks like I may have for instance two catch clauses for the same exception type. But when I try this I'll receive compile-time error.

public static void main (String[] args) throws java.lang.Exception
{
    try{
    } catch(RuntimeException ioe){
    } catch(NumberFormatException e){ //Already caught
    } 
}

IDEONE

Could you explain it using JLS?

St.Antario
  • 26,175
  • 41
  • 130
  • 318
  • You may have two, but `It is a compile-time error if a union of types contains two alternatives Di and Dj (i ≠ j) where Di is a subtype of Dj (§4.10.2).`. If you have to, put a try-catch(NFE) and rethrow it, and around that put a try-catch(RE) – Philipp Gayret Sep 30 '14 at 08:34
  • What is the point of catching the same exception more than one time in the same try statement? The compile error is pretty clear on that `unreachable catch block ...`. – A4L Sep 30 '14 at 08:36
  • @Philipp Do I have a union of type here? – St.Antario Sep 30 '14 at 08:38
  • 2
    [JLS 11.2.3](http://docs.oracle.com/javase/specs/jls/se8/html/jls-11.html#jls-11.2.3): _It is a compile-time error if a catch clause can catch an exception class E1 and a preceding catch clause of the immediately enclosing try statement can catch E1 or a superclass of E1._ – Seelenvirtuose Sep 30 '14 at 08:39
  • At last, the quote is exactly I was looking for. @Seelenvirtuose thank you. – St.Antario Sep 30 '14 at 08:40
  • @St.Antario also read this [answer](http://stackoverflow.com/a/25633634/1113392) – A4L Sep 30 '14 at 08:44

4 Answers4

2

NumberFormatException is a specialization of RuntimeException, so your NumberFormatException would be already caught by the first statement. You can switch the order of those two catch clauses, however; but keep in mind only one will be executed:

  • the NumberFormatException clause if the exception has this type
  • the RuntimeException clause for all other types of RuntimeException

As to why it is this way... Well that is how the language was designed. If all the matching catch blocks were executed, it would be really harder to handle errors correctly.

personne3000
  • 1,780
  • 3
  • 16
  • 27
  • _Well that is how the language was designed_ Could you provide the quote it proves? The language design must be completely described in the specification, right? – St.Antario Sep 30 '14 at 08:37
  • The part of the specification you quoted in your question exactly says this: the first catch clause that matches the exception is executed, which means only one matching catch clause is executed. As for the specification that says why you cannot write catch clauses in the order shown in your question, that's a different question (probably written somewhere else) – personne3000 Sep 30 '14 at 08:41
  • http://docs.oracle.com/javase/specs/jls/se8/html/jls-11.html#jls-11.2.3: "It is a compile-time error if a catch clause can catch an exception class E1 and a preceding catch clause of the immediately enclosing try statement can catch E1 or a superclass of E1." Edit: noticed it was posted before by Seelenvirtuose as comment to your question – personne3000 Sep 30 '14 at 08:46
1

Because RunTimeException is base class of NumberFormatException. http://docs.oracle.com/javase/7/docs/api/java/lang/NumberFormatException.html

KiranCK
  • 97
  • 7
1

The compiler error you get results from the hierarchy of the catched exceptions.

NumberFormatException extends IllegalArgumentException extends RuntimeException

Think of the catch block as safety nets. The NumberFormatException net is quite small as it is a special case of higher hierarchy exceptions. The RuntimeException net is one of the largest possible and will catch anything on this level (except Exception and Throwables, which are "superior"). What you did is place the small net below the large net. So the compiler is polite enough to give you the hint that the smaller net will never be reached.

(I know the metapher is not 100% precise, but in this context works fine.)

If you catch NumberFormatException first and then RuntimeException the compiler will happily agree! :-) You can also rethrow your caught exception from the first block.

LastFreeNickname
  • 1,445
  • 10
  • 17
1

NumberFormatException is a sub type of RuntimeException When you caught RuntimeException, It will caught all type of RuntimeException including NumberFormatException. That's why it's says already caught.

Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115