Java 如何从代码中删除受保护的void finalize()方法
Java方法受保护的void finalize()的问题,我试图寻找以前的问题,但仍然无法找到解决方法, 所以我的一个项目类调用了这个方法finalize(),这个方法在Java 9中被弃用了,也许他们会在下一个版本中删除它,所以我的公司想解决这个问题,我在这一部分得到了工作,这是我的坏运气。有人能建议我如何修复它吗?解决方案很简单,只需从类中删除该方法,但没有人允许我这样做,因为他们不想冒险。所以我需要解决这个问题 我不知道这对你们会有多大意义,我愿意为它寻找美妙的解决方案Java 如何从代码中删除受保护的void finalize()方法,java,garbage-collection,deprecated,data-cleaning,Java,Garbage Collection,Deprecated,Data Cleaning,Java方法受保护的void finalize()的问题,我试图寻找以前的问题,但仍然无法找到解决方法, 所以我的一个项目类调用了这个方法finalize(),这个方法在Java 9中被弃用了,也许他们会在下一个版本中删除它,所以我的公司想解决这个问题,我在这一部分得到了工作,这是我的坏运气。有人能建议我如何修复它吗?解决方案很简单,只需从类中删除该方法,但没有人允许我这样做,因为他们不想冒险。所以我需要解决这个问题 我不知道这对你们会有多大意义,我愿意为它寻找美妙的解决方案 private D
private DiskCache dc;
public void delete(DiskCacheItem item)
{
File f = file(item);
if (f != null)
{
log.debug("Delete " + f + ": " + f.delete());
}
files.remove(item);
items.remove(item);
}
private void validate()
{
dc.validate(this);
}
public void delete()
{
validate();
dc.delete(this);
}
protected void finalize()
{
try { delete(); } catch (Exception e) { }
}
对于此类具有使用后需要特殊处理的资源的类,应该实现。它提供了close()方法,您可以将删除代码放入其中。然后,可以将其用于以下情况:
try(YourClass yourObject = new YourClass()) {
// do work with yourObject
}
class MyClass implements AutoCloseable {
// create resources
@Override
public void close() throws Exception {
// delete resources here
}
}
编译器将自动在末尾放置finally块,并调用yourObject.close()代码>以安全地清理资源
编辑
示例类如下所示:
try(YourClass yourObject = new YourClass()) {
// do work with yourObject
}
class MyClass implements AutoCloseable {
// create resources
@Override
public void close() throws Exception {
// delete resources here
}
}
简单地删除finalize()
方法会遇到阻力,这是可以理解的。毕竟,它正在做一些有用的清理工作。问题是用什么来代替它
使项可自动关闭
可能会有所帮助,但这仅适用于在单个词法范围内使用该项的情况。这将使您能够使用try with资源。如果该项未在词法范围内使用,例如,如果它插入到多个数据结构中,则不能真正使用try with资源。这是您可能需要在项目无法访问后执行某些清理操作的地方
终结的首选替代方法是使用类似于。正常引用是“强”引用。当所有强引用都消失,只剩下弱引用时,该项变为“弱可及”。这会将引用排入引用队列;本质上,这是一个表示“该项不再是强可访问的”的事件,并且在接收到该事件时要采取的操作是执行一些清理操作
这种引用处理可能不方便,因此有另一种称为的机制可能更易于使用
使终结变得方便的是,finalize()
方法位于即将收集的对象本身上。终结的问题之一是通过创建一个新的强引用来“复活”对象
引用或更干净处理的诀窍是,您需要跟踪需要清理的内容,而不必保留对与其关联的对象的引用。在您的情况下,您有一个DiskCacheItem
,它显然保存在DiskCache
中。如果一个DiskCacheItem
实例即将被垃圾收集,您希望将其从DiskCache
中删除。很难从代码中分辨出来,但清理操作似乎是删除可能与DiskCacheItem
关联的文件
对象。如果是这样的话,下面是要做的:
创建一个负责执行清理操作的Cleaner
实例
创建一个包含要清理的内容的state类,在本例中是一个文件
将DiskCacheItem
添加到DiskCache
时,创建state类的实例,并将其注册到Cleaner,将其与清理操作关联。在这种情况下,清理操作是删除文件。这将返回的实例
如果在DiskCacheItem
上有显式的“关闭”或“删除”操作,请让它在关联的可清除对象上调用clean()
。这将立即调用清理操作
在将来的某个时候,如果未明确删除DiskCacheItem
,并且删除了对它的所有强引用,则它将成为幻影可访问的。这将导致清洁器调用清理操作
这有效地取代了finalization和finalization()
方法,不过要做到这一点,您必须重新安排数据结构
在所有这些之后,用更干净/可清洗的机制替换终结有什么意义?首先,您可以显式清理可清理的。当它最终变得无法访问时,它只是垃圾收集。不做额外的处理。对于finalization,即使已经从逻辑上清理了可终结对象,JVM仍然需要运行finalize()方法。第二,终结需要额外的GC过程来确保对象没有被“复活”。通过引用处理和清理,不可能“复活”对象。第三,finalize是脆弱的,很难正确实现finalize()方法。非常感谢您的响应,但仍然没有清晰地理解它,所以我们不需要在类中调用finalize()。如果你给我看一些上面代码的演示,那就太棒了:)使用AutoCloseable,没有必要在finalize()中也包含删除代码,因此可以删除该方法。你的任务有一个根本性的问题:你应该解决它,但不允许执行必要的步骤,“因为他们不想冒险”。看来,他们对保留这种方法的风险一无所知。推荐阅读资料:、和。简言之:删除该方法。顺便说一句,在log.debug(…)中隐藏影响f.delete()
的调用是非常危险的代码>语句。想象一下,如果一个程序员没有意识到这一微妙之处,就会a)删除或b)复制该语句,认为它只是一个调试输出语句,会发生什么?