为什么我需要调用close()或shutdown()方法?

时间:2013-04-17 21:32:48

标签: java garbage-collection shutdown finalize

我是Java新手,在高中时期有一些C ++背景。现在我正在努力创造一些东西,我选择Java作为编程语言。

我完成了我的作业,看了很多关于Java的“析构函数”, finalize()方法,以及 close() shutdown() 方法。但我仍然认为我不知道这应该如何工作(当然下面有更多信息)

好的,具体问题是为什么我需要调用 close() shutdown()方法?

在我的特定情况下,我正在使用一个我没有开发处理智能卡读卡器的类,但我已经看到了文件管理的情况,你需要调用 close( )方法,类似。

没有调用 close()方法与在C ++中释放内存的想法相同(那很糟糕)?意思是,我必须处理对象的删除或破坏......不是GC吗?

我试图用于智能卡读卡器的类不是最好的选项可能是一个选项,这个类实现 finalize()方法可能更好,所以当不再使用并为GC做好准备,释放内存(很可能是本机代码)和/或释放GC可能不知道如何操作的硬件资源。

但是文件管理类呢?这些是非常常用和维护的,为什么还需要一个 close()方法?我理解存在的目的,解锁文件,但为什么我要记得关闭它?一旦不再使用该对象,则至少在最常见的情况下自动解锁文件。

最后,使用实现 finalize()方法的类来包装需要关闭或关闭的类是一个正确的解决方法,在那里我调用 close()< / em>或 shutdown()方法?

我已经看到 finalize()方法不是很受欢迎,所以这就是我问这个问题应该如何解决的原因。

提前致谢

PS:我见过的:

Is there a destructor for Java?

Why would you ever implement finalize()?

http://www.codeguru.com/java/tij/tij0051.shtml

explain the close() method in Java in Layman's terms

Do I need to close files I perform File.getName() on?

4 个答案:

答案 0 :(得分:3)

大多数类都会在finalize方法中清理外部资源,但这与C ++的析构函数不同 - 只要不再使用对象就会调用析构函数,但是终结符不是调用直到一个对象被垃圾收集,你不知道什么时候会发生这种情况(如果你没有一个内存密集型程序,它可能永远不会发生)。所以,假设您正在分配一堆对象,每个对象都分配一个数据库连接(是的,您应该使用连接池,但这是假设的);你使用每个对象,然后将它的引用归零,这样它就可以在没有先关闭它们的数据库连接的情况下进行垃圾收集,现在你的数据库就会被废弃,因为它有太多的连接打开了。您可以调用System.gc希望这将清理连接,但这只是对垃圾收集器的一个建议,它执行一个集合,并且您的垃圾数据库连接的终结器可能不是智能的足以完全清理连接。

长话短说,您需要致电closeshutdown,因为您不知道对象的终结器是否/何时会运行,而您不知道它们有多好清理外部资源。

顺便说一句,您应该使用try-catch-finally块来确保调用closeshutdown - 将方法放在finally块中。或者,如果您使用的是Java7,请使用try-with-resources。

答案 1 :(得分:2)

java垃圾收集器会为你工作,但在某些情况下(使用套接字或数据库连接)你需要调用close方法(例如关闭与数据库的连接,或文件处理程序等)

有人调用连接的close()方法,然后将其变为null,如:

conn.close();
conn = null;

然后他们将它射入头部,以表明它已经死了。

答案 2 :(得分:1)

Java的垃圾收集会自动释放不再引用的内存。

它没有释放其他资源。因此,您需要一种显式方法来释放其他资源。

  

好的,具体问题是为什么我需要调用.close或.shutdown方法?

释放未自动处理的资源。

  

我理解存在的目的,解锁文件,但为什么我要记得关闭它?

如果你使用Java 7 try-with-resources,你就不必这样做。

  

最后,使用实现finalize方法的类包装需要关闭或关闭的类是否是一个正确的解决方法,并且我调用close或shutdown方法?

没有。在不再引用对象之后,您不能立即依赖于快速调用的finalize()方法。

答案 3 :(得分:1)

存在许多类来封装外部实体的服务。在许多情况下,一个类的有用性将取决于它要求外部实体代表做某事直到另行通知,这可能对该实体的其他潜在用户造成损害。要求外部实体代表其行事直至另行通知的类别承担了在不再需要其服务时通知外部实体的责任。

调用close()会告诉对象不再需要其服务;因此,(不再需要的)对象可以将消息传递给代表它的实体,即也不需要它们的服务。然后,此类通知可允许这些实体向其他潜在用户提供其服务。

垃圾收集操作假设系统知道何时需要内存,并且在系统用于可释放的内存之前,除去垃圾没有任何实际好处。 。这种哲学并不适用于使用close的大多数事物。在许多情况下,拥有资源的代码无法知道是否有其他人可能想要使用它。因此,代码通常应该仅在实际使用它们的持续时间内保留资源。一旦代码完成了资源,它就应该释放它,以便让任何可能需要它的人都可以使用它。