我应该如何在嵌套在 header 的方法中使用 `throws IOException` 的 `try-with-resources` 中使用 IOException?

How should I use IOException in `try-with-resources` nested in the method with`throws IOException` in the header?

AFAIK,标准 try-with-resources 形式

try(InputStream is= new ...){
    ... some reading from is
} catch (..){
    ... catching real problems
}
catch (IOException e) {
    ... if closing failed, do nothing - this clause is demanded by syntax
}

相当于:

try{
    InputStream is= new ...
    ... some reading from is
} catch (..){
    ... catching real problems
} finally {
    try{
        is.close();
    } catch (IOException e) {
        ... if closing failed, do nothing
    }
}

当然,第一个变体更简单。但我看到的情况是,第二个变体绝对没问题,而第一个变体变得难以理解。

想象一下这种情况,当您获得代码时,try(){} 出现在带有 throws IOExceptions 子句的函数中。

String readFromFile(...) throws IOException{
    ...
    try(...){
        ...
    }
}

第二个 catch 中的 IOException 吃掉所有 IOException,无论是否与关闭尝试有关。什么都不做。我想,在方法之外的某个地方有一段代码可以与 IOException 一起使用并且做了一些值得注意的事情。例如,记录堆栈。因此,当地的渔获量将永远达不到。我们对第二个 catch 子句不感兴趣,但通常,我们需要对第一个 catch 子句进行一些特殊的反应。

另一方面,如果我们删除关闭 catch(IOException e){} 子句,依靠方法 header 中的 throws,那对我们来说绝对无趣的关闭异常将被响应.

虽然我们正在通过 IOException 捕获关闭问题,但我看不出有什么办法可以解决这个问题。 Eclipse java 编辑器要求我为那个子句使用这个异常!

如何区分关闭时出现的 IOException 与出现在 try{} 中的其他 IOException body?

我认为 Java 是这件事的罪魁祸首。 close() 方法应该抛出与 IOException 不同的异常,调用者几乎无能为力。您唯一的解决方案是在重新抛出之前重新包装您感兴趣的 IOExceptions。

通常我所做的是将 try 块的全部内容提取到它自己的方法中,在那里我可以捕获任何 IOExceptions 并将它们作为自定义异常重新抛出。然后我可以在 catch 块中自己捕获剩余的 IOException。

public void foo() throws CustomException {

    try (InputStream is= new ...) {
        bar(is); //This catches internal IOExceptions and throws a CustomException
    }
    catch (IOException e) { //The close() exception
        

    }
}