Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a private 'property' a 'field'?

Tags:

oop

kotlin

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)?

like image 650
Eugene Avatar asked Dec 25 '22 07:12

Eugene


1 Answers

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.

like image 81
hotkey Avatar answered Dec 28 '22 08:12

hotkey