constructor - 在 Kotlin 初始化程序中使用 'this' - 替代解决方案,还是可以安全忽略?

标签 constructor kotlin

我有一个将自己注册为事件处理程序的类,带有事件服务:

interface CommunicationService {
    fun sendActivationMessage(toEmail: String)
}

abstract class EventCommunicationService : CommunicationService, AbstractEventHandler {
    constructor(eventService: EventService) {
        eventService.registerListener(this)
    }

    override fun onEvent(event: Event) {
        if (event.type == EventType.USER_CREATED) {
            sendActivationMessage(event.userEmail)        
        }
    }
}

想法可以是 EmailCommunicationService 或模拟测试版本等,它们在创建用户时不需要将自己注册为监听器。

但是 Kotlin 提示我:

Leaking 'this' in constructor of non-final class EventCommunicationService

我是。我可以很容易地忽略警告 - 但有更好的方法吗?

我试过使用 init { } block 而不是构造函数,但警告是一样的。

我基本上想要一个“构建后”回调或类似的回调,用于让此服务向构造函数中提供的 EventService 注册自身,因为这是此中间类型的要点。 p>

我理解为什么这是一个问题 - 但我不确定如何推理我的修复方法。

最佳答案

init block 实际上是构造函数的一部分(在 JVM 术语中),因此这无助于解决问题。通常忽略它是非常不安全的:参见 Leaking this in constructor warning出于某些原因(忽略已接受的答案,它的评论包含真正的内容,伊什塔尔的答案也是如此)。

一个选项(假设所有子类都有无参数构造函数,尽管它可以被扩展):

abstract class <T : EventCommunicationService> EventCommunicationServiceCompanion(private val creator: () -> T) {
    operator fun invoke(eventService: EventService): T {
        val obj = creator()
        eventService.registerListener(obj)
        return obj
    }
}

// a subclass of EventCommunicationService:
class MyService private constructor () : EventCommunicationService {
    companion object : EventCommunicationServiceCompanion<MyService>(MyService::new)
}

要创建一个 MyService,您仍然调用 MyService(eventService),但这实际上是伴随对象的 invoke 方法而不是构造函数.

关于constructor - 在 Kotlin 初始化程序中使用 'this' - 替代解决方案,还是可以安全忽略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51338319/

相关文章:

java - 从将为参数类型调用的 Java 类获取构造函数,不需要精确的参数和参数类型匹配

javascript - 如何为构造函数/原型(prototype)函数添加值?

android - 从 KOTLIN 的图库中选择多个图像(想要图像路径)

android - ANDAND 条件应为 'if true then false'

c++ - 在 C++ 中通过构造函数复制类

java - 为什么一个方法引用了 "throws"... 也抛出的 ctor?

android - "Place was called on a node which was placed already"

android - 如何在三个不同的 fragment 上观察来自实时数据android的数据

Kotlin 通过对每个元素求和将 'N' 列表组合在一起

c++ - 如何使用构造函数初始化另一个类中的对象?