为什么java中的close()方法抛出异常?

bui*_*ire 0 java exception

真的很愚蠢的问题,但也许有人有一个聪明的答案:

为什么 Java 中的 close() 方法会抛出异常?

在我看来 close() 是您在某种逻辑中调用的最终方法,因此它不应该失败,即使它失败了也应该在类中进行处理而不是抛出异常。

谢谢大家

PS:主要问题是关于对象设计和开发方法(不是特定于实现的)

现在你可能是对的,这是有道理的,但是如何很好地编写这种代码:

try {
} catch (Exception e) {
    logger.error("Error occured during copy", e);
} finally {
    // close all objects
    try {
        connection.close();
    } catch ( ... ) {
        ...
    } finally {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢。

Ste*_*n C 5

在我看来,这close()是您在某种逻辑中调用的最终方法,因此它不应该失败,即使它失败了也应该在类中进行处理而不是抛出异常。

有意见是好事。不幸的是,意见并不总是合理的:-)

考虑一下当您关闭FileOutputStream包裹在 a 中时会发生什么BufferedOutputStream

  1. 缓冲区中的任何未完成数据都将被刷新。
  2. 底层文件描述符是“关闭的”。

例如,如果文件系统已满,这些操作中的第一个可能会失败。

现在假设应用程序正在写入一个关键文件;例如,在 UNIX/Linux 系统上更新“/etc/passwd”的“adduser”程序。当然,应用程序将分两步完成。首先它会写出文件的新版本。然后,如果成功,它将新文件重命名为旧文件的路径名。(或类似的东西)

但是,如果我们close()按照您的意愿实施,应用程序级别将不知道close()未能将所有数据写出......并且“adduser”将继续重命名旧文件之上的新的不完整的“passwd”文件版本。哎呀!!您刚刚删除了“/etc/passwd”,没有人可以再登录了。(我希望你有一个方便的备份磁带:-))

教训:IOExceptions抛出的close()可能很重要。


你当然是对的,但在编写这种结构时感觉有些不对劲。

嗯,“try-with-resources”语法使这更好。但是,您无法避免IOException在某个级别处理 ,除非您可以自由声明close()在静态类型上connection不抛出异常。

try-with-resources 版本如下所示:

try (Connection c1 = openConnection(); 
     Connection c2 = openConnection()) {
   // so stuff
}
Run Code Online (Sandbox Code Playgroud)

双方c1c2会被关闭,即使他们的一个close()方法抛出异常。但是您仍然需要处理该异常;例如在封闭的处理程序中。(在资源关闭中try 内部抛出异常时会发生有趣的事情;请参阅http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html 中的“抑制异常”部分。)