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不一定会在第一次尝试中强制finalizers运行——有时对我来说需要多于一个才能成功。你本以为System/runFinalizers会这样做,但我在那上面一点运气都没有。

0

由gfredericks发表的评论

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

文档字符串部分描述了此行为:“reify始终实现clojure.lang.IObj并将表单的元数据转移到创建的对象中。”

0

评论者:wagjo

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

0

由gfredericks发表的评论

为了好玩,你可以做一些小技巧,比如

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

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

`

我还没运行过这个)

0

由gfredericks发表的评论

看起来通过{{reify}}生成的类都有接受元数据参数的构造函数,所以从整体上消除额外的对象似乎并不是什么不可能的事情。

我会继续挖掘这个问题。

0
...