“duck an exception”是什么意思?

35
在Java™教程的异常优点部分:

方法可以规避它内部抛出的任何异常,从而允许在调用堆栈更高层的方法中捕获它。

[...]

…规避异常需要中间方法做一些努力。必须在方法的throws子句中指定可能在其中抛出的所有已检查异常。

这里的“duck an exception”的意思是规避或忽略异常。

1
从教程中显示的伪代码来看,我认为它的意思是在方法本身中不要捕获异常,而是忽略它(对于已检查的异常,在throws子句中添加它),以便它可以被调用堆栈中更高层次的方法捕获。 - Andreas Fester
1
在这个编程上下文中,“duck”意味着将异常转发给调用者。 - Flown
23
“DUCK”的意思是低下头以避免被打击或被发现。为了避免方法被异常打击,你可以通过在方法声明中使用“throws”异常来将其抛出到调用栈的更高层。 - jmcg
所有这些关于鸭子的问题是怎么回事? - cobaltduck
4个回答

29

“Ducking”指的是为了避免被打击或被看到而低下头。在这种情况下,“闪避异常”只是意味着避免您的代码受到异常的影响。

为了让您的方法不受异常的影响,您可以在方法上声明throws异常,将其抛出到调用栈的更高层。

public void myMethod() throws IOException {

}

如果你不躲闪,就必须要接住它:

public void myMethod() {
    try {
       // ...  

    } catch(IOException e) {
      // handle exception
    }

26
很遗憾,由于Java没有提供一种让异常直接打到方法中的方式,因此这两种方法是唯一的选择。 - Sam Estep
1
@Elogent try { someCheckedExceptionHere(); } catch (SomeCheckedException e) { throw new RuntimeException(e); } 我经常这样做,当我需要处理一个已检查的异常,并且它的发生应该导致应用程序崩溃时(例如,无法加载描述启动应用程序所需的JavaFX场景的FXML文件)。 - randers

27

“躲避异常”意味着“不处理异常”。这实际上解释了名称的含义:duck的意思是“逃避;躲避”。

躲避异常的方法只是不处理它(例如,因为它不是其目的),并让异常被抛到调用方法中。

例如,考虑一个用于计算文件中行数的方法。这将是一个简单的实现(Java 8):

private static long numberOfLines(Path path) throws IOException {
    try (BufferedReader br = Files.newBufferedReader(path)) {
        return br.lines().count();
    }
}

请注意,这种方法不处理由Files.newBufferedReader(path)抛出的IOException,因为这不是该方法的目标。它会避让并让调用者适当处理。

请注意,调用者也可能避让异常并让它的调用者处理,等等。


5
我认为这意味着一种方法可以捕获异常并重新抛出它,以便其他方法可以捕获并根据需要处理它。或者只是抛出一个新的异常。或者避免捕获异常并让它沿调用堆栈向上冒泡。重点是有一个方法将异常处理委托给其他可能更适合处理给定异常的方法(例如通过访问必要的数据和/或状态)。但是(对于Java),这需要始终使用带有“throws”子句声明方法,这很容易成为样板文件。
如@jmcg的评论中所提到的,字面上“Duck”意味着低头以避免被打击或被看到(就像鸭子在河里一样)。

我认为“ducking”并不意味着捕获和重新抛出。部分内容“或避免捕获”听起来是正确的,但前面的两个句子可能是错误的。 - vikingsteve
@vikingsteve,也许是这样,但仍然涉及委托,一个方法确实可以捕获异常并重新抛出以委托其余部分。为了完整起见添加。 - Nikos M.
2
你解释了一些情况,但我认为你并没有真正回答这个问题——它非常具体:“duck”一个异常。如果它说“处理”一个异常,那么我认为你所描述的情况会更加有效。 - vikingsteve

1
我认为“duck”意味着重新抛出异常...换句话说,忽略它,希望其他人能够处理它 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接