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

时间:2014-01-17 16:59:34

标签: 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 {
        ...
    }
}

感谢。

5 个答案:

答案 0 :(得分:4)

  

在我看来,close()是你在某种逻辑中调用的最终方法,所以它不会失败,即使它失败了它应该在类中处理而不抛出异常。

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

考虑关闭FileOutputStream中包含的BufferedOutputStream时会发生什么:

  1. 刷新缓冲区中的任何未完成数据。
  2. 基础文件描述符已“关闭”。
  3. 第一个操作可能失败,例如,如果文件系统已满。

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

    但是如果我们按照您的意愿实现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
    }
    

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

答案 1 :(得分:3)

有许多类不涉及紧密操作,例如数据对象,地图,列表,因为资源管理对于这些对象来说很简单。

那些提供密切操作的类通常涉及更复杂的资源管理。他们经常涉及缓冲技术。

以文件编写器为例 - 在关闭时,缓冲文件内容应通过与文件同步来保留,但由于IO故障可能会失败。不要让失败保持沉默 - 因此可能会抛出异常让你知道。

答案 2 :(得分:2)

一般来说,如果最终的刷新失败,将抛出IOException。这可能有很多原因。可以说,你有OutputStream,由于某种原因还没有写入文件。调用close()将清除数据,但如果文件被锁定 - 则会引发IOException。

答案 3 :(得分:1)

如果你想更好地编写,你可以使用Java7的try-with-resource include:

http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
   return br.readLine();
}

它允许您定义一个资源,例如OutputStream,它会在您尝试结束时自动关闭。

不会改变它在引擎盖下的工作方式,但它更优雅。

答案 4 :(得分:0)

如果您尝试关闭的连接不存在,

close()函数也会抛出异常。例如。在JDBC SQL连接中,由于JDBC URL或用户名或密码不正确,首先可能没有打开连接,在这种情况下close()函数将引发异常。