为什么需要使用finally来关闭资源?

发布于 2024-12-08 07:02:51 字数 317 浏览 2 评论 0原文

大多数时候,我看到的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中关闭它?

Most of the time, the only thing I see a finally block used for is something like

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();
}

My question is, if f's scope ends with the enclosing block, why do we need to close it in the finally?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

清风疏影 2024-12-15 07:02:51

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

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

与文件句柄和任何其他资源相同。自己清理干净。

Because garbage collection is not the same thing as resource cleanup.

For example, if you have a JDBC Connection object that goes out of scope, there's no signal sent to the database server to indicate that open cursors and connections are no longer needed. Without those messages, you'll eventually exhaust the number of cursors and connections available to you.

Same with file handles and any other resource. Clean up after thyself.

分开我的手 2024-12-15 07:02:51

好吧,你给出了一个不好的例子 - 我怀疑你的意思是类似 FileInputStream 的东西 - 但基本原因是 Java 没有确定性终结。

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

除非您想让资源悬停任意长度的时间(并延迟垃圾收集,因为终结器在内存最终释放之前需要额外一轮收集),否则您应该显式关闭资源。

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

Well you've given a bad example - I suspect you meant something like FileInputStream - but the basic reason is that Java doesn't have deterministic finalization.

The scope of the variable f ends with the block it's declared in (not the try block), but that doesn't mean there are necessarily no "live" references to the object any more - and the garbage collector will neither finalize the object nor garbage collect it in any deterministic manner.

Unless you want to leave resources hanging around for an arbitrary length of time (and delay garbage collection, as finalizers require an extra round of collection before the memory is finally released), you should explicitly close resources.

Basically Java does not support RAII in the same way that C++ does; you shouldn't try to use it as if it were C++.

独﹏钓一江月 2024-12-15 07:02:51

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

because finally is called everytime, even if you get an exception raised. the finally block insure you that the file/connection will be closed.

忆梦 2024-12-15 07:02:51

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

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

The reason is that Java doesn't guarantee that an object will be garbage-collected as soon as a particular reference to it falls out of scope. So for objects that reference limited system resources, such as a file descriptor, it's not enough to wait for garbage collection.

Note though, that java.io.File is not actually such an object.

雨后咖啡店 2024-12-15 07:02:51

我们通过 try catch finally 来处理异常,每次执行时finally都会阻塞,但不能保证catch,因为catch块只有在传入参数匹配的异常时才会执行。
例如,如果我们打开了任何数据库连接,那么我们必须在离开之前关闭它,这必须在finally中实现。

We handled exception by try catch finally ,finally block every time execute but there is no guarantee of catch because catch block execute only if exception passed in parameter matched.
For example if we have open any database connection so it is must we closed it before leave,tht must be implemented into finally.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文