为什么我需要最终使用来关闭资源?

时间:2011-10-04 17:56:42

标签: java try-catch finally

大多数情况下,我唯一看到的是使用finally块的东西就像是

FileInputStream f;
try{
    f= new FileInputStream("sample.txt");
    //something that uses f and sometimes throws an exception
}
catch(IOException ex){
    /* Handle it somehow */
}
finally{
    f.close();
}

我的问题是,如果f的范围以封闭块结束,为什么我们需要在finally中关闭它?

5 个答案:

答案 0 :(得分:19)

因为垃圾收集与资源清理相同。

例如,如果JDBC连接对象超出范围,则没有信号发送到数据库服务器以指示不再需要打开游标和连接。如果没有这些消息,您最终会耗尽可用的游标和连接数。

与文件句柄和任何其他资源相同。在你自己之后清理。

答案 1 :(得分:6)

嗯,你给出了一个糟糕的例子 - 我怀疑你的意思是FileInputStream - 但基本原因是Java没有确定性的最终确定。

变量 f的范围以其声明的块(不是try块)结束,但这并不意味着必然没有“直播” “再次引用该对象 - 垃圾收集器既不会最终确定对象,也不会以任何确定的方式收集垃圾。

除非你想让资源闲置一段任意的时间(并且延迟垃圾收集,因为终结器需要在最终释放内存之前进行额外的收集),你应该明确地关闭资源。

基本上,Java 以与C ++相同的方式支持RAII;你不应该试着像使用C ++一样使用它。

答案 2 :(得分:2)

因为每次都会调用finally,即使你遇到了异常。 finally块确保文件/连接将被关闭。

答案 3 :(得分:0)

原因是Java不保证一旦对象的特定引用超出范围就会对对象进行垃圾收集。因此,对于引用有限系统资源的对象(例如文件描述符),等待垃圾回收是不够的。

但请注意,java.io.File实际上不是这样的对象。

答案 4 :(得分:0)

我们最后通过try catch处理异常,最后每次执行都阻塞但是没有catch的保证因为catch块只在参数匹配时传递异常才执行。 例如,如果我们打开任何数据库连接,那么我们必须在离开之前关闭它,必须最终实现。