Есть ли аннотация, которая вызывает предупреждение, если передается объект, который фиксирует вложенное «это»?
У меня есть функция Kotlin с этой подписью:
fun registerDisposer(obj: Any, disposer: Closeable)
Что делает функция, так это присоединяется к фантомной ссылке и упорядочивает ее закрытие при сборке мусора (т. е. когда объект фантомной ссылки ставится в очередь). Класс
obj
предполагается назвать это примерно так:
class Holder(private val res1: Closeable, private val res2: Closeable) {
init {
registerDisposer(this, object: Closeable {
private val res1 = this@Holder.res1
private val res2 = this@Holder.res2
override fun close() {
res1.close()
res2.close()
}
})
}
}
(Давайте проигнорируем, является ли хорошей идеей полагаться на это с общим
Closeable
с; Фактически рассматриваемый ресурс - это указатель, управляемый собственным кодом/JNI - я пытаюсь следовать совету Ханса Бёма . Но все это не имеет особого отношения к данному вопросу.)
Я беспокоюсь, что такой дизайн позволяет слишком легко непреднамеренно передать объект, который захватывает
this
из внешней области, создавая цикл ссылок и вообще предотвращая сборку мусора объекта:
registerDisposer(this, Closeable {
this.res1.close()
this.res2.close()
})
Есть ли аннотация, которую я могу добавить к
disposer
параметр, который вызовет предупреждение в этой ситуации?
1 ответ
На момент написания этой статьи ответ кажется таким: вероятно, нет.
оказывается
registerDisposer
функция уже существует, так как
register
метод
java.lang.ref.Cleaner
, и у него нет такой аннотации.
В Android есть аналогичная аннотация для
android.os.AsyncTask
, но это просто предупреждает о любом анонимном объекте, имеющем
AsyncTask
как его базовый класс, независимо от того, захватывает он или нет. (Это имеет смысл в Java, где анонимные классы всегда захватывают
this
, но не в Котлине.)