I have 2 suggestions how
lateinit could be improved.
lateinit can’t be
val. It’s OK for class with something like
onCreate method, where the field must be initialized from the Kotlin method. But there are many environments, where fields are initialized using reflection, like Spring DI or JavaEE DI.
lateinit var looks strange. I don’t want to change those values from Kotlin code, but language doesn’t help me to show that intent. IMO it should be possible to use
lateinit val to express the intent that this field must be initialized by reflection. I don’t really see any problems with that.
Second: there are some restrictions:
lateinit can’t be used with the primitive and nullable types. I’ll describe my usecase: I use
lateinit-like mechanism for my data classes. I load some fields from the DB and then I use those fields. I don’t necessarily want to load every field from DB, sometimes I only need few of them. But on the other hand, if i made a mistake and I’m trying to use a non-initialized value, I want to have an exception. So
lateinit would be a perfect match for that use-case, but my fields can be nullable or primitive. So I have to distinguish between null and uninitialized value. I implemented it using Map<KProperty, Any?> and delegate properties, but native support would be better, both from performance reasons and from usability reasons.
For nullable and primitive types compiler could generate a bitset field (1
long field enough for 64 nullable fields). Getter method would check proper bit and setter method would set proper bit. It would be much more efficient than a
Also some method, probably somewhere in the reflection package, to check whether field was initialized, would be helpful too. Of course I can just get the value and catch an exception, but exception throw/catch is quite slow, compared with simple comparison.
Now the only tricky case is using
lateinit val with nullable or primitive types. Reflection will write the value to the field directly, so it’s not possible to detect initialization, at least if the value was initialized using null or 0/false/etc. Probably that particular combination should be forbidden.