3

C #Dispose,在IDisposable.

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

4

3 回答 3

1

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

虽然此接口方法声明为 throw Exception,但强烈建议实现者声明该close方法的具体实现以抛出更具体的异常,或者如果关闭操作不会失败,则根本不抛出异常。

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

于 2014-10-20T07:21:12.987 回答
1

因为 Java 的设计者能够using在实现他们自己的 try-with-resources 功能之前看到 .NET 块中的清理异常处理出现的问题,所以他们能够对其进行改进。在 .NET 中,Dispose块的作者经常面临一个令人不快的选择,要么吞下任何发生的异常,从而错误地让调用程序相信一切都很好,要么让异常以这样的方式渗出,Dispose以消除任何异常的任何证据。以前的例外。幸运的是,Java 避免了这个问题。

如果 try-with-resources 块正常成功并且close也正常成功,则外部代码认为一切正常。如果该部分发生异常tryclose正常成功,则外部代码将看到 try-block 异常。如果try正常完成但close抛出异常,外部代码将看到close异常。如果trythrows, but closealso throws, 那么外部代码将看到try异常但也能够检索发生在其中的任何异常close(并且如果多个嵌套的 try-with-resources 在 期间抛出异常close,则所有抛出的异常都将可供外部代码使用)。

因此,与经常迫使作者扼杀由 .NET 引发的一些潜在严重异常的 .NET 设计不同Dispose,Java 的设计倾向于在出现严重close错误时抛出异常,以至于不应允许调用者相信一切都很好。

于 2014-10-21T15:27:28.170 回答
0

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

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

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

于 2014-10-20T07:18:27.107 回答