为什么当 GC 可以释放所有连接时需要完成
Why finalize is required when GC can free all connections
我有一个对象。它打开了一个FileConnection
.
现在,我引用了对象 null
.
然后 GC
[Garbage-Collecter] 运行。
因此,GC
将释放对象并关闭对象持有的 FileConnection
。
那为什么我需要覆盖 finalize 方法?
finalize()
恰好在 GC 销毁对象之前调用。它永远不会发生,finalize()
方法永远不会被调用。
如果你拿了一个资源(即打开一个文件),你必须正确地手动释放它。您可以使用 AutoCloseable
界面。
示例:
try (Scanner scan = new Scanner(new File("xxx"))) {
// do smth.
} // scan.close() will be automatically called here
或更严格地说:
Scanner scan = null;
try {
scan = new Scanner(new File("xxx"));
} finally {
if (scan != null)
scan.close(); // instead of scan.finalize();
}
P.S. 永远不要使用 finalize()
方法 - 这是过时的并且用于非常具体的低级解决方案。如果你问这个问题,那说明这不是你的。
您不需要覆盖 finalize
方法。最好完全忘记 finalize
方法,它已被弃用。
但是您确实需要在使用完后立即关闭该资源。 GC 可能会将未使用的对象保留很长时间。如果您依赖 GC 关闭系统资源,您可以 运行 在 OS 级别处理文件句柄、锁或套接字等内容。
这些都是有限的资源。
我有一个对象。它打开了一个FileConnection
.
现在,我引用了对象 null
.
然后 GC
[Garbage-Collecter] 运行。
因此,GC
将释放对象并关闭对象持有的 FileConnection
。
那为什么我需要覆盖 finalize 方法?
finalize()
恰好在 GC 销毁对象之前调用。它永远不会发生,finalize()
方法永远不会被调用。
如果你拿了一个资源(即打开一个文件),你必须正确地手动释放它。您可以使用 AutoCloseable
界面。
示例:
try (Scanner scan = new Scanner(new File("xxx"))) {
// do smth.
} // scan.close() will be automatically called here
或更严格地说:
Scanner scan = null;
try {
scan = new Scanner(new File("xxx"));
} finally {
if (scan != null)
scan.close(); // instead of scan.finalize();
}
P.S. 永远不要使用 finalize()
方法 - 这是过时的并且用于非常具体的低级解决方案。如果你问这个问题,那说明这不是你的。
您不需要覆盖 finalize
方法。最好完全忘记 finalize
方法,它已被弃用。
但是您确实需要在使用完后立即关闭该资源。 GC 可能会将未使用的对象保留很长时间。如果您依赖 GC 关闭系统资源,您可以 运行 在 OS 级别处理文件句柄、锁或套接字等内容。 这些都是有限的资源。