为什么Java multi-catch不能处理与子类相关的类型



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

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换成.. SQLException,它有效。规范内容如下:

如果类型联合包含两个,则为编译时错误 替代 Di 和 Dj (i ≠ j),其中 Di 是 Dj 的子类型。

我无法理解这背后的理由。当然,在我的示例中,多重捕获是完全多余的,因为我也可以只捕获IOException。但是,使我的代码片段合法有什么害处呢?当然,一种做法必须有危害才能成为非法吗?

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

catch (IOException | FileNotFoundException e)

如果

catch (IOException e)

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

规范讨论了

多捕获子句可以被认为是单捕获子句的序列

所以你的代码有点像

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

这也被javac拒绝了。在这种情况下,错误是合理的,因为无法访问第 2 条。


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

但是,使我的代码片段合法有什么害处呢?当然,一种做法必须有危害才能成为非法吗?

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

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

最新更新