非常愚蠢的问题,但也许有人有一个明智的答案:
为什么Java中的close()方法抛出异常?
在我看来,close()是你在某种逻辑中调用的最终方法,因此它不应该失败,即使它失败了它应该在类中处理而不抛出异常。
谢谢所有
PS:主要是关于对象设计和开发方法(不是特定于实现)的问题
现在你可能是对的,这是有道理的,但如何很好地写出这种代码:
try {
} catch (Exception e) {
logger.error("Error occured during copy", e);
} finally {
// close all objects
try {
connection.close();
} catch ( ... ) {
...
} finally {
...
}
}
感谢。
答案 0 :(得分:4)
在我看来,
close()
是你在某种逻辑中调用的最终方法,所以它不会失败,即使它失败了它应该在类中处理而不抛出异常。
有意见是好的。不幸的是,意见并不总是合理的: - )
考虑关闭FileOutputStream
中包含的BufferedOutputStream
时会发生什么:
第一个操作可能失败,例如,如果文件系统已满。
现在假设应用程序正在写一个关键文件;例如一个“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
}
c1
和c2
都会被关闭,即使其中一个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()函数将引发异常。