9

这是一段不能编译的代码:

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
{}

如果异常类型没有通过子类关联,一切都像魅力一样工作。如果您将IOException我的代码片段中的 换成 say.. SQLException,它就可以工作。规范内容如下:

如果类型的联合包含两个备选方案 Di 和 Dj (i ≠ j),则这是编译时错误,其中 Di 是 Dj 的子类型。

我无法理解这背后的原因。当然,我的示例中的 multi-catch 完全是多余的,因为我也可以只捕获一个IOException。但是让我的代码片段合法有什么害处呢?一种做法一定是有害的,才能成为非法的吗?

4

3 回答 3

11

在同一个 catch 中包含给定异常的子类根本没有任何意义,而且令人困惑,因为无论您指定的子类如何,您都将进入 catch。例如,你为什么要写

catch (IOException | FileNotFoundException e)

如果

catch (IOException e)

会有完全相同的行为吗?这简直令人困惑。

于 2013-11-06T17:47:47.847 回答
5

规范讨论了

一个 multi-catch 子句可以被认为是一系列 uni-catch 子句

所以你的代码有点像

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

这也被 javac 拒绝了。在这种情况下,错误是有道理的,因为第二个子句不可达。


但是,我认为不应该禁止联合类型。充其量应该是一个警告。

于 2013-11-06T18:51:24.993 回答
4

但是让我的代码片段合法有什么害处呢?一种做法一定是有害的,才能成为非法的吗?

这是令人困惑的代码-您可以通过仅捕获来简化代码IOException,而看起来您确实需要分别捕获它们。

我不能肯定地说这是理由,但这是我用来证明它的理由。当开发人员可以编写更简单的代码开始时,阻止他们滥用功能。

于 2013-11-06T17:47:51.297 回答