Java 在不使用任何catch语句的情况下尝试block

Java 在不使用任何catch语句的情况下尝试block,java,exception,try-catch,Java,Exception,Try Catch,我在阅读Java教科书中关于异常和断言的一章时,遇到了这段代码,我对此有疑问 public boolean searchFor(String file, String word) throws StreamException { Stream input = null; try { input = new Stream(file); while (!input.eof()) if (input.next().equ

我在阅读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
,以便在清理后将生成的任何异常传递给调用代码,包括调用close抛出的任何
StreamException

我的印象是,包含
throws
子句是允许程序员抛出特定类(或子类)的原因一个异常,当且仅当类或它的一个超类在
throws
子句中时,才可以抛出一个类。但是这里有一个
throws
子句,在
try
块中没有
throw
语句。那么,首先包含该子句的意义是什么?在代码中的什么位置de>流异常是否被捕获

在代码中的什么地方会捕获到
StreamException


try
有一个
finally
但没有
catch
。将执行
finally
,而
异常将传播到调用方

关键是确保流关闭,而不管方法中发生了什么。遍历strea时抛出的任何内容m被抛出到调用方(每个调用方依次可以捕获异常或将异常抛出到其调用方,依此类推)


如果这段代码使用try with resources,那么这将确保close抛出的异常不能掩盖在流中迭代时抛出的异常。(因为如果close方法抛出异常,那么调用方就会看到异常,即使try块中有东西抛出了。)如果我没有错,
StreamException
将不会从此类处理,而是在具有
catch(StreamException se){…}
的类上处理,即调用方

无论是否引发异常,
finally
块都将始终执行,因此它将始终关闭流

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

  • try-catch
    (将执行try或catch块)
  • try catch finally
    (try或catch块将被执行,而finally块将无论如何执行)
  • 最后重试
    (将执行两个块)

  • 抛出一些异常
    写入,后跟方法签名

    意味着在方法块可能引发编译时异常的一侧编写的某些代码

    根据java的
    异常
    规则。当任何
    编译时异常
    抛出时,它需要声明或处理。

    这里,在您的代码中没有编写任何
    throw
    语句,但是来自块的一些方法调用需要
    处理或声明它

    throws Exception would propagate to the invoker.
    

    Java7引入了
    trywithresources
    语句,可以完美地处理这种情况

    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
    语句或
    finally
    块中都抛出异常,则返回异常与抑制异常之间有一个小的区别。有关更多详细信息,请参阅。

    如果它确实抛出异常,则finally块仍将被执行。异常将从方法中抛出。@WalterM但我认为在throws子句中包含异常的意义在于,编译器允许您使用特定的catch语句来引用可以抛出的不同类型的异常。如果选中的异常可以在没有catch语句的情况下抛出,那么ha的意义何在是否有catch语句?可能是重复的!是的,我想我忘记了,如果在第一个块中找不到符合其类型的catch语句,异常将继续向外搜索。现在它更有意义了。谢谢!正如Nathan所指出的,异常在不掩蔽任何
    异常方面有额外的优势在
    finally
    块中的
    上(我假设您的书早于
    try with resources
    )。我正在阅读Java编程语言,第四版。我在索引中看到的是
    try-catch
    try-catch-finally
    ,和
    try-finally
    。因此,是的,它肯定早于
    try-with-resources
    语句。我会详细阅读。从Java 8开始,还有
    try-with
    块处理这个pr优雅地回答这个问题。@hubatish我很高兴看到你的答案,并举一个例子,因为我从未尝试过:)