我有一个将自己注册为事件处理程序的类,带有事件服务:
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/