11

在 Eclipse 中添加 try/catch 块时,它为我提供了“使用 try/multi-catch 环绕”或“使用 try/catch 环绕”的选项。

这是 try/multi-catch:

try {
    save.load(new FileInputStream(file.getAbsolutePath()));
}
catch (FileNotFoundException | IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

这是单一的尝试/捕获:

try {
    save.load(new FileInputStream(file.getAbsolutePath()));
}
catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

使用其中一种有什么好处/影响?如果我是正确的,第一个示例将在抛出任何一个异常时执行 catch 块并产生 SAME CATCH,而第二个示例将在启用单独的 catch 块时基于异常抛出一个 catch。

还有什么我应该知道的吗?我以前从未使用过它们,也不知道它们是否值得使用。

4

5 回答 5

8

tl;dr Mutlicatch 单独处理事情,多个 catch 块更灵活,更易于操作。这两种技术可以结合使用。

如果您有一个可以抛出许多不同异常类型的 try 语句,您将需要多个 catch 块。它的代码多一点,但提供了更大的灵活性。

例如,如果使用套接字,则 SocketException 可能会被捕获,只不过是重新连接和/或错误消息(因为不经意断开电缆这样简单的事情可能会导致这种情况)

如果捕获到空指针异常(尽管未检查),您将需要写入日志并在此处紧急着陆,清理您可以清理的内容,并可能在代码方面进行相当多的回溯。

此外,这可以进一步细分,其中不同类型的“常见”异常可能会导致采取不同的操作(例如连接丢失与名称未解析对最终用户在第一次连接尝试时产生不同的影响)和不同的“重度”异常也以不同的方式处理。

虽然您可以有一个(多种异常类型)catch 块,但它会单独对所有异常采取类似的操作(以与基于拔出电缆的条件相同的方式向用户呈现空指针异常)或需要if e instanceof FooException块会降低可读性。

您还可以将两者结合起来,将所有“常见”异常多捕获为重试和漂亮消息,并将所有严重异常合并为强制清理和关闭

您不希望对绊倒的电缆进行堆栈跟踪,也不希望清除丢失的对象。

于 2013-07-14T00:54:37.297 回答
2

这是一个选择的事情。您想要平衡可读性、可移植性、可维护性以及以不同方式处理不同的异常。

所以平衡使用......如果你所有的捕获使用相同的处理块,那么使用第一种形式,因为那只是一个代码块,你不会一遍又一遍地重复自己。编译器可以为您优化一些东西。

另一方面,如果您以不同方式处理每个异常,请使用第二种形式。

这是一个有点宽泛的问题,答案取决于您的目标。

于 2013-07-14T00:57:13.587 回答
2

我相信您的第一个代码片段仅适用于您的 JDK 是 Java JDK 7。而第二个代码片段仍将在 JDK 7 及更低版本中运行。

如果您有一行代码可能引发不同类型的异常,并且您想以类似的方式处理它们,Multicatch 将适合您,因为它节省了几行代码。

但是,如果您有一行代码会抛出多个异常,并且您想单独处理这些异常,那么单个 catch 异常会更适合您。

于 2013-07-14T00:57:17.463 回答
1

如果你想对所有异常做同样的事情,try-multi catch 和 try-catch 是一样的,只是前者更短。所有的程序员都是懒惰的。

当您想为不同的异常做不同的事情时:

} catch(AException e) {
    System.err.println("AException occured");
} catch(BException e) {
    System.err.println("BException occured");
}

Try-multi catch 不是正确的选择。


} catch(AException | BException e) {
    System.err.println("A or B Exception occured");
}

请注意, 的类型是和e最接近的公共超类型。AExceptionBException

于 2013-07-14T01:05:01.667 回答
0

看,try-catch 结构的实际用途是您可以将特定的错误处理函数应用于特定的异常。在您的情况下,除了要打印堆栈跟踪之外,您似乎不希望发生任何事情。例如,如果我希望在抛出 FileIOException 时关闭窗口,并且我只想在发生任何其他异常时显示一条错误消息,那么拥有多个 try-catch 块将很有用,就像您在第二个中所写的那样代码块。但是,在此应用程序中,您可能只想拥有这样的捕获:

try {
    save.load(new FileInputStream(file.getAbsolutePath()));
} catch (Exception e) {
    e.printStackTrace();
}

这将为所有异常打印一个轨迹跟踪。:)

于 2013-07-14T00:57:40.293 回答