Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从代码中删除受保护的void finalize()方法_Java_Garbage Collection_Deprecated_Data Cleaning - Fatal编程技术网

Java 如何从代码中删除受保护的void finalize()方法

Java 如何从代码中删除受保护的void finalize()方法,java,garbage-collection,deprecated,data-cleaning,Java,Garbage Collection,Deprecated,Data Cleaning,Java方法受保护的void finalize()的问题,我试图寻找以前的问题,但仍然无法找到解决方法, 所以我的一个项目类调用了这个方法finalize(),这个方法在Java 9中被弃用了,也许他们会在下一个版本中删除它,所以我的公司想解决这个问题,我在这一部分得到了工作,这是我的坏运气。有人能建议我如何修复它吗?解决方案很简单,只需从类中删除该方法,但没有人允许我这样做,因为他们不想冒险。所以我需要解决这个问题 我不知道这对你们会有多大意义,我愿意为它寻找美妙的解决方案 private D

Java方法受保护的void finalize()的问题,我试图寻找以前的问题,但仍然无法找到解决方法, 所以我的一个项目类调用了这个方法finalize(),这个方法在Java 9中被弃用了,也许他们会在下一个版本中删除它,所以我的公司想解决这个问题,我在这一部分得到了工作,这是我的坏运气。有人能建议我如何修复它吗?解决方案很简单,只需从类中删除该方法,但没有人允许我这样做,因为他们不想冒险。所以我需要解决这个问题

我不知道这对你们会有多大意义,我愿意为它寻找美妙的解决方案

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)复制该语句,认为它只是一个调试输出语句,会发生什么?