如何用垃圾收集语言(例如Java / Scala)替换/实现RAII?

时间:2014-03-27 23:55:00

标签: c# java programming-languages d

在Java和C#等语言中,有一个"析构函数"的概念。 RAII如何与这一概念正交,如何在这些语言中实现?

2 个答案:

答案 0 :(得分:7)

最大的区别是调用终结器/析构函数时。对于RAII,当变量超出范围时,它总是被调用,它具有一定的保证时间。使用垃圾收集,在系统确定对象不再使用后随时调用它。

从概念上讲,垃圾收集是具有无限生命周期的对象的实现细节。就您的程序而言,GC对象始终存在。这就是为什么它没有被收集,直到没有更多的参考,所以程序永远不需要知道它被收集。终结者是这个小说中的一个小漏洞,但它们仍然受制于一些规则:你不知道什么时候会被召唤。你甚至不知道/他们是否会被召唤。

您可以在D中并排看到差异.D中的struct析构函数为您提供RAII。类析构函数与垃圾收集一起使用。 (大多数情况下,你也可以调整它们,它们并不是一个很难的规则。)

类析构函数:

  • 除非成员是类中的值类型,否则无法引用成员。 GC可能已经收集了它们,因为在析构函数运行时,该类已经/已经/被认为已经死亡。

  • 无法运行,直到在内存压力下请求分配,触发GC收集扫描。它可能永远不会运行。

只有在特殊情况下它才能替代RAII。 RAII的保证允许您在稀缺资源的情况下使用它。

答案 1 :(得分:3)

在没有它的语言中替换RAII是try-finally。它保证即使抛出异常也会调用finally中的清理代码。拉动插头时它不会工作但是你有不同的问题。

没有尝试 - 最后你必须非常小心,所有代码路径都将进行适当的清理,这远非琐碎的路径