Kotlin vs Object Pooling - nullify lateinit variable
Nullable type is a good thing. Until you prevent memory allocation to fight Garbage Collection pauses. I want to nullify lateinit variable - I can’t. Or can I?
Nullify lateinit
Sometimes you have to nullify things. There are multiple reasons, most of them is the external code. To reduce amount of work that has to be done by Garbage Collector (even if JVM is doesn’t memleak as ActionScript)
class AIComponent : PooledComponent {
lateinit var steerable: SteerableEntity
override fun reset() {
steerable = null // ERROR! I CAN'T DO THAT!
}
}
Easy “solution” is not to use lateinit at all by making it nullable:
class AIComponent : PooledComponent {
var steerable: SteerableEntity? = null
override fun reset() {
steerable = null
}
}
but accessing nullable variable is not convenient. Instead of just using steerable I would have to write steerable!! .
Use Reflection!
No, well, no. It’s too slow. Inspection and stuff. Especially on Android.
There’s a more performant way - cache your reflection as bytecode instructions. And there is a library for it - ReflectASM. Let’s try it out:
val aiComponent: AIComponent = getAiComponent()
// this should be cached statically
val access = FieldAccess.get(AIComponent::class.java)
val fieldIndex = access.getIndex("steerable")
// call this in reset()
access.set(aiComponent, fieldIndex, null)
And finally, this is how we achieve nullable lateinit:
class AIComponent : PooledComponent {
lateinit var steerable: SteerableEntity
override fun reset() {
nullifyThings(this)
}
object companion {
val steerableFieldAccess = FieldAccess.get(AIComponent::class.java)
val steerableFieldIndex = access.getIndex("steerable")
fun nullifyThings(obj: AIComponent) {
steerableFieldAccess.set(obj, steerableFieldIndex, null)
}
}
}
If you have to do this in a performant way, that’s a choice. I don’t expect to find a quicker way than with cached bytecode.