Probably with hacks. Did you know a final field in Java can change its value? And I'm not talking about his reflection to make it non-final. With ordinary code only, you can read a final field before it's been initialized, so it still holds its default zero value. For example "final int x = calcX();" and have calcX print the value of x, it will be zero.
There's a whole bunch of specification language describing how constants aren't actually constant in specific situations.
I don't know Kotlin but I assume it does the same thing: until the non-nullable field gets initialized, it holds null and violates the type system.
Kotlin works around this by not exposing the backing field directly; a "field" becomes a "property" which has a getter and setter under the hood. Attempts to read uninitialized properties are compile-time errors. You can turn these into runtime errors using the "lateinit" keyword.
Kotlin still has a hole where you can run code in "init" blocks which are executed sequentially on object construction; in one, you can call a function that is defined after an unmodifiable property, and it will see the uninitiailized value.
Nothing stops me from sticking my dick into a blender either, yet it works fine for most of the things (the blender). Both Java’s notion of final and Kotlin’s nullability work great for 99.999 use cases and you really need to go out of your way to break them.
`lateinit var` was not added to Kotlin to handle nullability, but to address specific Android design where system components like Activity cannot realisticly initialize fields in their constructors. Outside of Android it shouldn't be too commonly used.
"lateinit var" predates Android's adoption of Kotlin by years and was added because fields initialized after construction by frameworks are common in many contexts, but having nullability in the language makes that annoying.
Probably with hacks. Did you know a final field in Java can change its value? And I'm not talking about his reflection to make it non-final. With ordinary code only, you can read a final field before it's been initialized, so it still holds its default zero value. For example "final int x = calcX();" and have calcX print the value of x, it will be zero.
There's a whole bunch of specification language describing how constants aren't actually constant in specific situations.
I don't know Kotlin but I assume it does the same thing: until the non-nullable field gets initialized, it holds null and violates the type system.
Kotlin works around this by not exposing the backing field directly; a "field" becomes a "property" which has a getter and setter under the hood. Attempts to read uninitialized properties are compile-time errors. You can turn these into runtime errors using the "lateinit" keyword.
Kotlin still has a hole where you can run code in "init" blocks which are executed sequentially on object construction; in one, you can call a function that is defined after an unmodifiable property, and it will see the uninitiailized value.
Nothing stops me from sticking my dick into a blender either, yet it works fine for most of the things (the blender). Both Java’s notion of final and Kotlin’s nullability work great for 99.999 use cases and you really need to go out of your way to break them.
A lot of the language rules are required to make its approach to nullability work. Hence odd keywords like "lateinit var".
`lateinit var` was not added to Kotlin to handle nullability, but to address specific Android design where system components like Activity cannot realisticly initialize fields in their constructors. Outside of Android it shouldn't be too commonly used.
"lateinit var" predates Android's adoption of Kotlin by years and was added because fields initialized after construction by frameworks are common in many contexts, but having nullability in the language makes that annoying.