[英]Is it meaningful for AutoCloseable's close method to throw an exception? How should this be handled?
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.