5

我是 Java 新手,高中时有 C++ 方面的背景。现在我正在尝试做点什么,我选择了 Java 作为编程语言。

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

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

在我的特殊情况下,我正在使用一个我没有开发的处理智能卡读卡器的类,但我已经看到文件管理的情况,你必须调用close()方法,将是相似的.

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

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

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

最后,用实现finalize()方法的类包装需要关闭或关闭的类,并在那里调用close()shutdown()方法是否是一种适当的解决方法?

我已经看到finalize()方法不是很流行,所以这就是为什么我要问这个问题应该如何解决。

提前致谢

胡安

PS:我所看到的:

Java有析构函数吗?

你为什么要实现 finalize()?

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

用 Layman 的术语解释 Java 中的 close() 方法

我是否需要关闭执行 File.getName() 的文件?

4

4 回答 4

3

大多数类将在其方法中清理其外部资源finalize,但这与 C++ 的析构函数不同——一旦不再使用对象就会调用析构函数,但直到对象被垃圾回收后才会调用终结器,并且您不知道这何时会发生(如果您没有内存密集型程序,它可能永远不会发生)。因此,假设您正在分配一堆对象,每个对象都分配一个数据库连接(是的,您应该使用连接池,但这是一个假设);您使用每个对象,然后将其引用清空,以便可以在不先关闭其数据库连接的情况下对其进行垃圾收集,现在您的数据库将因打开太多连接而对您产生影响。你可以打电话System.gc希望这会清理连接,但这只是对垃圾收集器执行收集的建议,并且您的垃圾数据库连接的终结器可能不够聪明,无法完全清理连接。

长话短说,您需要调用closeshutdown因为您不知道对象的终结器是否/何时运行,并且您不知道它们在清理外部资源方面有多好。

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

于 2013-04-17T21:41:01.580 回答
2

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

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

conn.close();
conn = null;

然后他们朝它的头部开枪,以表明它已经死了。

于 2013-04-17T21:36:35.427 回答
1

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

它不会释放其他资源。因此,您需要一个显式方法来释放其他资源。

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

释放未自动处置的资源。

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

如果您使用 Java 7 的try-with-resources,则不必这样做。

最后,用实现 finalize 方法的类包装需要关闭或关闭的类并在那里调用 close 或 shutdown 方法是否是一种适当的解决方法?

不可以。你不能依赖在finalize()一个对象不再被引用之后很快或根本就调用的方法。

于 2013-04-17T21:35:57.160 回答
1

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

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

垃圾收集是在系统知道何时需要内存的前提下运行的,并且在系统可以使用可以释放的内存之前,摆脱垃圾并没有任何真正的好处。这种哲学不适用于大多数使用close. 在许多情况下,拥有资源的代码无法知道其他人是否想要使用它。因此,代码通常应尝试仅在资源实际使用期间保留资源。一旦代码完成了资源,它应该释放它,以便让其他任何可能需要它的人都可以使用它。

于 2014-03-26T22:03:11.880 回答