如何在 kotlin 中实现 finalize()?

Posted

技术标签:

【中文标题】如何在 kotlin 中实现 finalize()?【英文标题】:How to implement finalize() in kotlin? 【发布时间】:2017-10-02 17:00:29 【问题描述】:

今天我在 kotlin 中实现 Closeable,就像我过去在 java 中所做的那样,我想实现 finalize() 作为最后的后备手段,以防客户端代码忘记关闭它,渲染未回收的关键资源。我认为这个资源足够重要,可以添加这个后备,尽管这个后备不可靠。但是,kotlin.Any 没有声明 finalize 方法,这意味着我不能简单地这样做:

class Resource: Closeable 
    fun close() 
    override fun finalize()  close()

这不好,至少没有它应该的那么好。现在我恢复到纯 Java 作为一种解决方法。有谁知道如何在纯 Kotlin 中做到这一点?

PS:我目前的解决方法:

FinalizedCloseable.java:

public abstract class FinalizedCloseable implement Closeable 
    @Override protected void finalize()  close(); 

科特林:

class Resource: FinalizedCloseable(), Closeable 
    fun close() 
    override fun finalize()  close()

但是这种解决方法需要一个超类。如果下次我的另一个 Resource 已经有了一个超类,那么如果没有大量样板文件,这个解决方法就行不通。


编辑:现在我知道如何实现 finalize(),但是 IDEA kotlin 插件不够聪明,无法知道这是一个终结器,因此用一些警告标记它。苦苦挣扎了一阵子,终于找到了如何抑制这些警告,特地分享一下:

class C 
    @Suppress("ProtectedInFinal", "Unused") protected fun finalize() 

【问题讨论】:

kotlinlang.org/docs/reference/java-interop.html#finalize @ean5533 呃,我没有完整阅读那么长的互操作文档,现在是我的惩罚。还是谢谢你。 你读过“finalize() called on strongly reachable object in Java 8”吗?最重要的是,你最好不要这样做。除非您的代码涉及直接处理系统资源的native 代码,否则您的类将成为实际代表资源的另一个对象的包装器,并让包装器的可访问性确定实际资源的生命周期(可能仍然可以访问并且使用中),意味着提出严重的问题…… @Holger 感谢您指出这一点。但我的问题是,只有一部分资源被一个处理程序消耗,其余的将存储在一个池中,直到另一个处理程序,甚至失败的处理程序再次被拉出。因此,偶尔失败一次在我的软件中不是问题。但是,我不想冒险失去他们中的任何一个,否则会有三百人的军队撞到我的前门。顺便说一句,在我的机器上,链接中示例中的FinalizeThis::finalize 在我的机器上从未调用过一次 这都是 JVM 特定的。除了过早被调用的危险之外,还有很大的可能永远不会被执行,至少不会在关键时间范围内。垃圾收集旨在管理内存,只要有足够的内存或垃圾收集器对回收不需要终结的对象的存储感到满意,它就可能不会运行或只是忽略具有终结器的对象。还有多线程问题…… 【参考方案1】:

official documentation 涵盖了这一点。

要覆盖 finalize(),你需要做的只是简单地声明它,而不使用 override 关键字:

class C 
    protected fun finalize() 
        // finalization logic
    

【讨论】:

秒杀我 :) 谢谢!这就是我所需要的!但是为什么 *** 禁止在粘贴 12 分钟之前选择 anwser... 好的,它可以工作,但是如何在其中调用super.finilize()?我反编译了生成的java代码,那里没有超级调用。 @Boris 是的,如果你扩展了一个有代码的类。但是,当您扩展的任何类都没有覆盖它时,就不需要它了。但是,如果您扩展的类允许它,您应该可以调用 super.finalize 并且一切正常。 但这有效吗?当对象准备好被释放时,这个函数会运行吗?

以上是关于如何在 kotlin 中实现 finalize()?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Kotlin 中实现 OnClickListener 接口? [复制]

如何在 Kotlin 中实现 switch-case 语句

如何在 KOTLIN 中实现 buttonX.setOnClickListener(this)? [复制]

如何在 android studio 中实现 Admob 插页式广告 - Kotlin

如何使用 Kotlin 在 RecyclerView Adapter 中实现 onClick 并进行数据绑定

如何在 kotlin 中实现 List<data class>(子列表)的 parcelable?