繁体   English   中英

AutoCloseable的close方法抛出异常是否有意义? 应如何处理?

[英]Is it meaningful for AutoCloseable's close method to throw an exception? How should this be handled?

在C#中,在IDisposableDispose方法中抛出异常被认为是不好的做法

相比之下,在java中, AutoCloseableclose方法允许抛出任何异常并强制调用者以某种方式处理它。 但如果发生这种情况,合理预期的调用者会怎样做? 这表明以某种方式关闭资源的尝试失败了。 那么用户在继续之前是否必须再次尝试关闭资源,或许是某种指数退避?

AutoCloseable的设计是Java检查异常的结果。 有些实现只需要能够抛出已检查的异常,因此需要throws Exception 但是, 实现应声明抛出更多特定类型 (如果有):

虽然声明此接口方法抛出Exception ,但强烈建议实现者声明close方法的具体实现以抛出更多特定异常,或者如果close操作不能失败则不抛出任何异常。

如果有办法避免异常,你不应该抛出异常,但你不能总是避免它。 例如,当关闭具有未刷新数据的BufferedOutputStream时,缓冲流有两个选项; 忽略未写入的数据并关闭或将其写入流,这可能导致异常被抛出。

因为Java的设计者能够在实现他们自己的try-with-resources功能之前看到.NET using块中的清理 - 异常处理所引起的问题,所以他们能够改进它。 在.NET中, Dispose块的作者在吞下任何发生的异常之间经常面临一种令人不快的选择,从而错误地让调用程序认为一切正常,或者让异常从Dispose中渗透出来以消除任何证据任何先前的例外情况。 幸运的是,Java避免了这个问题。

如果try-with-resources块正常成功并且close也正常成功,则外部代码会正常查看所有内容。 如果try部分发生异常但是正常close成功,外部代码将看到try-block异常。 如果try正常完成但是close抛出,则外部代码将看到close异常。 如果try抛出,但也close也抛出,那么外部代码将看到try异常,但也能够检索close中发生的任何异常(如果多个嵌套的try-with-resources在close期间抛出异常,则所有抛出的异常将是可用于外部代码)。

因此,与.NET的设计往往迫使作者扼杀通过抛出一些潜在的严重的异常Dispose ,具有Java的设计主张close抛出一个异常,任何时候不顺心的充分错误调用者不应该被允许相信,一切都很好。

看起来涉及资源的每个操作(包括隐式close()调用)都被视为try {}块的一部分。 即使在技术/语法上思考,资源也会在{}括号之外提到。

这意味着如果在close()期间抛出IOException,它将被与您的try相关联的一些catch()子句捕获(或者它将向上传播)。

关于可能需要抛出异常的原因 :close()可能导致flush(),flush()可能导致write(),而write()可能会失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM