original source : https://kotlinlang.org/docs/reference/properties.html#backing-fields


var data =  listOf<SleepNight>()
   set(value) {
       field = value

이를 보다가 찾아 보게된 자료이다.



Backing Fields

Fields cannot be declared directly in Kotlin classes. However, when a property needs a backing field, Kotlin provides it automatically. This backing field can be referenced in the accessors using the   field   identifier:

var counter = 0 // Note: the initializer assigns the backing field directly
   set(value) {
       if (value >= 0) field = value

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.

For example, in the following case there will be no backing field:

val isEmpty: Boolean
   get() = this.size == 0

kotlin android codelab 강좌에서 본적이 있음.

LiveData를 사용하기 위해서 MutableLiveData를 사용했음. 그와 비슷한 원리이다.

Backing Properties

If you want to do something that does not fit into this “implicit backing field” scheme, you can always fall back to having a backing property:

private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
   get() {
       if (_table == null) {
           _table = HashMap() // Type parameters are inferred
       return _table ?: throw AssertionError(“Set to null by another thread”)

On the JVM: The access to private properties with default getters and setters is optimized so no function call overhead is introduced in this case.

java의 field와 kotlin에서의 property의 개념 차이


This is an example of a Java field:

public String name = "Marcin";

Here is an example of a Kotlin property:

var name: String = "Marcin"

They both look very similar, but these are two different concepts. Direct Java equivalent of above Kotlin property is following:

private String name = "Marcin";
public String getName() {
   return name;
}public void setName(String name) {
   this.name = name;

The default implementation of Kotlin property includes field and accessors (getter for val, and getter and setter for var). Thanks to that, we can always replace accessors default implementation with a custom one. For instance, if we want to accept only non-blank values, then we can define the following setter:

var name: String = "Marcin"
   set(value) {
       if (value.isNotBlank())
           field = value
   }name = "Marcin"
name = ""
print(name) // Prints: Marcin

If we want to be sure that the returned property value is capitalized, we can define a custom getter which capitalizes it:

var name: String = "Marcin"
   get() = field.capitalize()name = "marcin"
print(name) // Prints: Marcin

The key fact regarding properties is that they actually are defined by their accessors. A property does not need to include any field at all. When we define custom accessors that are not using any field, then the field is not generated:

var name: String
   get() = "Marcin"

This is why we can use property delegation. See example of property delegate below:

var name: String by NameDelegate()

Above code is compiled to the following implementation:

val name$delegate = NameDelegate()
var name: String
   get() = name$delegate.getValue(this, this::name)
   set(value) { name$delegate.setValue(this, this::name, value) }

Moreover, while a property is defined by its accessors, we can specify it in the interface:

interface Person {
   val name: String

Such declaration means that there must be a getter defined in classes that implement interface Person.

As you can clearly see, Kotlin properties give developers much bigger possibilities than Java fields. Yet, they look nearly the same and Kotlin properties can be used exactly the same as Java fields. This is a great example, how Kotlin hides complexity under the carpet and gives us possibilities even if some developers remain unaware of them.

This post is the fourth part of the Kotlin programmer dictionary. To stay up-to-date with new parts, just follow this medium or observe me on Twitter.

If you need some help then remember that I am open for consultations.

If you like it, remember to clap. Note that if you hold the clap button, you can leave more claps.

Comments are closed.

Post Navigation