c# - 为什么java和c#有终结器?

标签 c# java language-features finalizer

我不是很理解java和c#等语言为什么会有终结器。据我所知,他们:

  • 不保证运行(在 java 中)
  • 如果他们确实运行了,他们可能会在相关对象成为最终确定对象之后运行任意时间
  • 并且(至少在 java 中),它们会导致惊人的巨大性能下降,甚至无法坚持上课。

那么为什么要添加它们呢?我问了一个 friend ,他咕哝着说“你想有一切可能的机会来清理数据库连接之类的东西”,但这让我觉得这是一种不好的做法。为什么你应该依赖具有上述属性的东西来做任何东西,甚至作为最后一道防线?尤其是当类似的东西被设计到任何 API 中时,该 API 将被 mock 不存在。

最佳答案

嗯,在某些情况下,它们非常有用。

在 .NET CLR 中,例如:

  • are not guaranteed to run

如果程序没有被终止,终结器最终将始终运行。它只是不确定何时运行。

  • if they do run, they may run an arbitrary amount of time after the object in question becomes a candidate for finalization

这是事实,但是,它们仍然运行。

在 .NET 中,这非常非常有用。在 .NET 中,将 native 的非 .NET 资源包装到 .NET 类中是很常见的。通过实现终结器,您可以保证正确清理 native 资源。否则,用户将被迫调用方法来执行清理,这会大大降低垃圾收集器的效率。

准确知道何时释放您的( native )资源并不总是那么容易 - 通过实现终结器,您可以保证它们将被正确清理,即使您的类以不太完美的方式使用也是如此。

  • and (at least in java), they incur an amazingly huge performance hit to even stick on a class

同样,.NET CLR 的 GC 在这方面有优势。如果您实现了正确的接口(interface) (IDisposable),并且如果开发人员正确地实现了它,您就可以避免昂贵的完成部分的发生。这样做的方法是用户定义的清理方法可以调用 GC.SuppressFinalize ,绕过终结器。

这为您提供了两全其美的方法 - 您可以实现终结器和 IDisposable。如果您的用户正确处理了您的对象,则终结器不会产生任何影响。如果他们不这样做,终结器(最终)会运行并清理您的非托管资源,但您会在运行时遇到(小的)性能损失。

关于c# - 为什么java和c#有终结器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1850742/

相关文章:

c# - 使用 TextWriter.Synchronized 或锁定多线程文件 IO - C# WPF .net 4.5

java - 如何告诉项目下载内部依赖?

java - 无法在谷歌地图 Activity 中导航,它总是会生成回到我当前的位置

java - Java 中的方法中是否使用了自由 float block ?

Python type() or __class__, == or is

C# 将 csv 转换为 xls(使用现有的 csv 文件)

c# - 将集合均匀分布到新数组中

c# - 在用户设置中存储 array[,]

java - 是否有用于本地(非 TCP)连接的 JMX 服务 URL?

Objective-C:如何防止抽象泄漏