没有任何 catch 语句的 Try 块

Try block without any catch statements

我正在通读 Java 教科书中关于异常和断言的一章,遇到了我有疑问的这段代码。

public boolean searchFor(String file, String word)
    throws StreamException
{
    Stream input = null;

    try {
        input = new Stream(file);
        while (!input.eof())
            if (input.next().equals(word))
                return true;
        return false;         //not found
    } finally {
        if (input != null)
            input.close();
    }
}

在下一段中,文本说“searchFor 方法声明它抛出 StreamException,以便生成的任何异常在清理后传递给调用代码,包括任何 StreamException 由关闭调用抛出。

我的印象是包含 throws 子句允许程序员抛出特定的 class(或子 class)异常,并且 class 当且仅当它或其超class之一在 throws 子句中时才会被抛出。但是这里,try 块中有一个 throws 子句,没有 throw 语句。那么首先包含该子句的意义何在? StreamException 会在代码的什么地方被捕获?

And where in the code would a StreamException be caught?

try 有一个 finally 但没有 catchfinally 将执行,而 Exception 将传播到 调用者

重点是确保流被关闭,无论方法中发生了什么。在流中迭代时抛出的任何东西都会抛给调用者。 (每个调用者依次可以自由地捕获异常或将其抛给它的调用者,等等。)

如果此代码使用 try-with-resources 那么这将确保在关闭时抛出的异常不会掩盖在遍历流时抛出的异常。 (如果 close 方法抛出异常,那么这就是调用者所看到的,即使 try 块中的某些东西抛出了某些东西。)

如果我没记错的话,StreamException 不会从这个 class 中处理,而是在 catch (StreamException se) {...} 中处理,即调用者。

无论是否抛出异常,finally 块将始终 执行,因此它将始终关闭流。

您可以拥有 3 种不同类型的 try 方块:

  1. try-catch(将执行try或catch块)
  2. try-catch-finally(Try 或 catch 块将被执行,并且无论如何都会执行 finally 块)
  3. try-finally(两个块都会被执行)

throws SomeException写完后跟方法签名,

表示在该方法块中编写的一些代码可能会抛出编译时异常。

并按照 java 的 exception 规则。当任何 compile-time exception 抛出时,它 需要声明或处理。

在这里,在你的代码中没有写任何throw语句,但是来自块的一些方法调用需要handle or declare它。

throws Exception would propagate to the invoker.

Java 7介绍了完美处理这种情况的try-with-resources语句。

public boolean searchFor(String file, String word)
    throws StreamException
{
    try (Stream input = new Stream(file)) {
        while (!input.eof()) {
            if (input.next().equals(word)) {
                return true;
            }
        }
        return false;         //not found
    }
}

这与您的示例做同样的事情,并且适用于任何实现 AutoCloseable 的东西。

任何替换代码的注意事项:如果在 try 块和 try-with 语句或 [=14= 中都抛出异常,则返回异常与抑制异常存在细微差别] 堵塞。有关详细信息,请参阅 Oracle docs