In Kotlin, suppose, I have class:
class MyKotlinClass {
lateinit var field: String
}
According to docs:
Late-Initialized properties are also exposed as fields. The visibility of the field will be the same as the visibility of lateinit property setter.
I can use in java code either myKotlinClass.field
or myKotlinClass.getField()
. I want to disable field access and remain only access through getter and setter.
How can I achieve this and remain lateinit modifier?
The lateinit var lookupKey in Kotlin defined a property without a value set directly. The value is set to the property later. The compiler takes care to add assertions to make sure it is not possible to read the value before it is not initialized.
lateinit: The whole point is to make sure that we initialize the object before we use it, or else it should throw an Exception letting us know that we are missing something in the code. In the context of android, we can use this for data binding and view model objects.
Backing fields The field identifier can only be used in the accessors of the property. A backing field will be generated for a property if it uses the default implementation of at least one of the accessors, or if a custom accessor references it through the field identifier.
A private field that stores the data exposed by a public property is called a backing store or backing field. Fields typically store the data that must be accessible to more than one type method and must be stored for longer than the lifetime of any single method.
You can use @JvmSynthetic
that hides declarations from Java (and not from Kotlin). Just annotate the backing field of the property:
@field:JvmSynthetic
lateinit var field: String
Though the field will remain public
in the bytecode, it will also have the synthetic
modifier, which prevents it from being used in Java sources. However, the field seems to be still accessible through reflection at runtime.
See also: another question about @JvmSynthetic
(though no definite answer there).
The classical solution to this problem would be to use property delegation:
import kotlin.properties.Delegates
class MyKotlinClass {
var field: String by Delegates.notNull()
}
This code does exactly what you asked for in the question
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With