【问题标题】:How do you write a deconstructor in Java?你如何用 Java 编写解构器?
【发布时间】:2011-01-27 21:29:28
【问题描述】:

我遇到了这个问题并正在寻找一些想法?

【问题讨论】:

  • 遇到这个问题....在考试中?在你的家庭作业中? ;-)
  • 他们不是也问过解构函数吗?
  • 如果我在一次采访中被问到,我早就走了。
  • @skaffman - 我会以“这是一个棘手的问题!”开始我的回答。如果面试官白了我一眼,那么我可能会走出去。

标签: java


【解决方案1】:

您不需要(也不应该尝试使用)析构函数 - 或者它们在 Java 中称为“终结器”。

VM 规范确实允许 VM 实现从不调用它们。因此它们对于资源释放等不可靠。一般来说,任何对象的finalize()方法中的代码都可以在对象被垃圾回收之前被VM调用,但这不是强制性的,你应该避免。

【讨论】:

  • finalize() 不是析构函数,它具有不同且非常具体的含义。
  • 你是对的。我试图通过解释它不适合资源释放和其他通常使用析构函数的清理任务来说明概念上的差异。
  • 关于 finalize 唯一应该知道的是:永远不要使用它,否则小耶稣会哭:-)!
  • 您应该使用它,但如果您要关闭的资源仍处于打开状态,则在调用它时记录。这样你就知道你错过了什么可以去修复它。我个人也不这样做,我只是确保我的代码是正确的:-)
  • @TofuBeer。应该注意的是,这样做会给垃圾收集器带来(显着的?)额外负担;如果有的话,应该谨慎行事。有关更多详细信息,请阅读使用 ReferenceQueue 的替代方案,从 java.lang.ref 的包文档开始。
【解决方案2】:

Java 是垃圾回收的,因此无法判断您的 析构函数 何时会被调用(您的对象何时会被垃圾回收)。

有一个finalize(继承)方法,但由于上述确切原因,您不能依赖它(您无法预测何时以及是否会调用它)。

【讨论】:

    【解决方案3】:

    如果你只是需要清理一些资源,可以拨打Runtime.getRuntime().addShutdownHook

    【讨论】:

      【解决方案4】:

      Java 中的自动对象“破坏”永远不会在保证的时间内发生。垃圾收集的唯一受赠者是在收集对象之前将调用终结器方法。当然,垃圾收集器永远不能保证运行,或者在它运行时做任何事情。所以不能保证finalize方法会被调用。

      如果您想在 Java 中模拟 C++ 析构函数,最好的方法是使用以下惯用语(在异常处理方面存在差异 - 我将在这里仅展示最简单的情况):

      final Resource r;
      
      r = new Resource();
      
      try
      {
          r.use();
      }
      finally
      {
          r.cleanup();
      }
      

      “清理”方法是“析构函数”。

      这更像是C++ Resource Acquisition Is Initialization idiom,它确实适用于基于堆栈的对象,但不是那么好。

      【讨论】:

      • 其他人说不能保证 finalize() 会被调用。如果我理解正确,您是说如果对象被垃圾收集器销毁,则将调用 finalize。所以 finalize() 不会被调用的唯一原因是垃圾收集器没有碰巧销毁那个特定的对象?
      • 是的,如果要收集对象,则将调用终结器。但是,没有被授权者每个对象都被收集,因此不能保证终结器会被调用。看看java.sun.com/docs/books/jls/third_edition/html/… - “Java 编程语言没有指定多久会调用终结器,只是说它会在对象的存储被重用之前发生。”
      【解决方案5】:

      您可以查看此以获取有关最终​​确定的更多信息 - finalize() method

      【讨论】:

        【解决方案6】:

        由于其他人在谈论正常情况.. 在特殊情况下,您要创建destroy()destruct()releaseExternalResources()shutdown() 等应该主动调用的方法 由控制该实例生命周期的实体。

        例如,一个对象可以是一个 ActiveObject,其中有活动线程。在这种情况下,您需要关闭它们,否则您将出现内存泄漏。

        虽然人们可能不会称其为析构函数......

        在旁注中,我猜面试问题本来是一个技巧问题!

        【讨论】:

          【解决方案7】:

          Try-with-resources 从 Java 1.7 开始提供

          任何继承自CloseableAutocloseable 的东西都可以使用它。

          https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

          try (FileReader br = new FileReader(path)) {
              return br.readLine();
          }
          

          这将自动调用close 函数,该函数保证在块的末尾被调用。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多