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

大多数时候,我唯一看到的块块就是这样的

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中关闭它?

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

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

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

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

变量 f的范围以它声明的块(不是try块)结束,但这并不意味着不再需要对该对象进行“实时”引用 – 并且垃圾收集器既不会最终确定对象也不会垃圾以任何确定的方式收集它。

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

基本上Java不像C ++那样支持RAII; 你不应该尝试使用它,就像它是C ++一样。

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

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

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

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