Looking into properties in Kotlin, this concept is a somewhat new to me so I'm curious, is it legitimate to state that a private property
is a field
(instance variable)?
You can consider properties as values that you can get (and set for mutable ones), but they can have custom and overridable behaviour and might not be actually stored. So properties are not fields.
In Kotlin, all member properties, private
or not, can have a backing field, but it is not necessary.
Property with a backing field:
var counter = 0
Here, 0
is put into the backing field, and the property behaves like a field: getting a value from it returns the value stored in the field, setting a value to it just stores the value into the backing field. But it's not a field, e.g. for Java it will still be a pair of getter and setter.
Private properties with no custom accessors are optimized and compiled into fields to avoid function call overhead, but it's rather an implementation detail, and adding a custom accessor will also change the bytecode that accessing the property is compiled into.
var counter = 0
get() = field + 1
set(value) { if (value >= 0) field = value }
Here again the property has a backing field, but its behaviour is different, custom accessors get()
and set(...)
will be executed in statements like counter = something
or val x = counter
. This is true for accessing the property both from within and from outside the class, and private
properties are not different here.
The backing field can be accessed directly only inside the accessors code by a soft keyword field
, it is not exposed to the other code. If you want to access the backing value from somewhere else, you have to define another backing property. You can expose a backing field to Java code by adding @JvmField
annotation to the property (this won't make it accessible from Kotlin).
Property without a backing field
When a property has no initializer and has at least get()
, it is a property with no backing field:
val time: Long get() = System.currentTimeMillis()
No backing field will be generated for it, but you can use another property as a backing property as stated above.
Properties with no backing field can also be extension properties, which is quite far from fields:
val String.isCapitalized: Boolean get() = length > 0 && this[0].isUpperCase()
These can also be private
, but it will have different semantics.
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