9

Here is a piece of code that shall not compile:

void multiCatch()
{
    try {
        throwIOFile();
    }
    // FileNotFoundException extends IOException, hence this
    // does not compile ("alternatives" related by sub classing):
    catch (IOException | FileNotFoundException e) { }
}

void throwIOFile() throws IOException, FileNotFoundException
{}

Everything works like a charm had not the exception types been related by sub classing. If you swap the IOException in my code snippet for say.. SQLException, it works. The specification reads:

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.

I can not understand the rationale behind this. Granted, the multi-catch in my example is completely redundant since I could just as well catch an IOException only. But what would be the harm in making my code snippet legal? Surely there has to be a harm for a practice to become illegal?

Martin Andersson
  • 18,072
  • 9
  • 87
  • 115

3 Answers3

11

Having subclasses of a given exception in the same catch simply doesn't make any sense and it's confusing, because you're going to enter the catch anyway no matter the subclasses you specify. For example, why are you going to write

catch (IOException | FileNotFoundException e)

if

catch (IOException e)

will have the exact same behavior? It's simply confusing.

m0skit0
  • 25,268
  • 11
  • 79
  • 127
  • 2
    I agree, I see no reason to try and particularize something that was meant to be generic in the first place. We are trying to reduce code duplication so we group together all the exceptions that should be treated the same way, after all. – Morfic Nov 06 '13 at 18:10
5

The spec discusses that

A multi-catch clause can be thought of as a sequence of uni-catch clauses

so your code is kind of like

    try {
        throwIOFile();
    }
    catch (IOException e) { }
    catch (FileNotFoundException e) { }  // error

This is rejected by javac too. In this case, the error is justified, since the 2nd clause is unreachable.


However, I don't think the union type should be forbidden. It should be a warning at best.

ZhongYu
  • 19,446
  • 5
  • 33
  • 61
  • Agree with you, almost completely. Thing is I don't like adding rules and complexity to a language if there is no real gain in doing so. The suggestion to rewrite our multi-catch example should be provided by the IDE or a book. I have a hard time defending a warning too. What exactly is the warning supposed to warn against? To continue on my example. It is legal for me to write a throws clause that enlist both: `throws IOException, FileNotFoundException`. In this case, we say that it is a good thing to be explicit of what one could expect. Doesn't the same hold true for multi-catch? – Martin Andersson Nov 07 '13 at 13:46
  • Nor do we make it illegal with magic numbers or other discouraged best practices. We don't even print a warning =) My reasoning says there should actually be a real harm in allowing the multi-catch statement to be legal. But I just can't think of such a case. – Martin Andersson Nov 07 '13 at 13:48
4

But what would be the harm in making my code snippet legal? Surely there has to be a harm for a practice to become illegal?

It's confusing code - you can simplify the code by just catching IOException, whereas it looks like you really need to catch both of them separately.

I can't say for sure that that's the rationale, but that's the rationale I'd use to justify it. Stop developers from abusing a feature when they can just write simpler code to start with.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194