请分享您的想法,参加 2024 Clojure 状态调查!

欢迎!请查看 关于 页面了解更多关于如何使用本页面的信息。

0
Clojure

即使具体化对象仍然可达时,也会对它们调用 Finalize。其次,在适当的时间再次调用。

`
user=> (def x (reify Object (finalize [o] (println "OH MY!"))))

'user/x

user=> (System/gc)
nil
OH MY!
user=> x

<user$reify1496 user$reify1496@53fb35af>

user=> (System/gc)
nil
user=> (def x nil)

'user/x

user=> (System/gc)
nilOH MY!
`

Deftype 似乎工作得很好

`
user=> (deftype T [] Object (finalize [o] (println "great success")))
user.T
user=> (def y (->T))

'user/y

user=> (System/gc)
nil
user=> (def y nil)

'user/y

user=> (System/gc)
great success
`

6 答案

0

由 alexmiller 发布的评论

仅备注:调用 System/gc 并不一定会导致最终化器在第一次尝试时运行——有时对我来说要多次尝试才能成功。你以为 System/runFinalizers 会这样做,但我用那个完全失败了。

0

由 gfredericks 发布的评论

{{reify}} 实际上创建了两个对象——第一个是在 * 创建的,然后 {{reify}} 立即对它调用 {{with-meta}},创建一个副本。

文档字符串大致描述了这种行为:“reify 总是实现 clojure.lang.IObj,并将形式的数据元数据转移到创建的对象中。”

0

评论人:wagjo

哦,所以finalizer在reify中是不被允许的。我认为在文档中应该提到这一点。

0

由 gfredericks 发布的评论

出于趣味,你可以做一些技巧性的东西,比如

`
^::second-object
(reify Object
(finalize [self]

(when (::second-object (meta self))
  ...)))

`

我还没有实际上运行这段代码

0

由 gfredericks 发布的评论

看起来由{{reify}}生成的类总是有一个带有元数据参数的构造函数,所以消除额外的对象似乎并不出奇。

我会试着继续深入研究这个。

0
参考: https://clojure.atlassian.net/browse/CLJ-1347 (由wagjo报告)
...