Backing field in Kotlin

Backing field in Kotlin

Understand Kotlin Backing field

Backing field is a concept introduced in Kotlin the programming language, a simple but forgotten concept you should learn about.

What you will learn:

  1. What is the backing field in Kotlin?
  2. Why do we need a backing field?
  3. When does it get created?

Before answering these questions let's introduce the way JAVA handles class properties declaration and initialization and how we can approach data hiding in a class.

Properties in JAVA:

let's declare a Student class with some related properties:

public class Student {
    private String name;

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

as we can see, a very simple way to declare a class with a property, and to control its state value, we hide its property name by making it private and create accessors to manage to get and set value.

let's break it down:

  1. First we need a local property to set a value in it.
  2. We need a local property to get the value from it.
  3. If we don't use a local property inside any of the accessors, then we don't need the local property.

like below, we don't need to store a name value, as we compute it by concatenating the first and the second name, so we don't need the name property.

public class Student {
    // private String name;  ---> no need for the name property.
    private String firstName;
    private String lastName;

    public Student(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getName() {
        return firstName + " " + secondName ;
    }
}

Let's move to Kotlin:

Kotlin is a concise language, that saves you boilerplate code, and helps us by generating some code out of the box for us.

to declare a Student class with a name property, all you have to do is:

class Student(private val name: String)

cool, right ๐Ÿ˜Ž

but what is happening behind the scene?

Kotlin will generate accessor functions for getting and setting the property value, at the same time, it provides you with a mechanism to customize the accessors' logic, so to implement the previous Java example we need to do the following:

class Student (private val firstName: String, private val secondName: String){
    val name: String
        get() = "$firstName $secondName"
}

How to refer to Backing field?

Let's have an example:

class Student {
    var age: Int = 0
        get() = 2022 - field
        set(value) {
            field = value
        }
}

To refer to the backing field you need to use the field modifier as you can see in the above example.

Let's answer questions:

1. What is a Backing field in Kotlin? Backing field purpose is to store the property value, think of it as a box when you set a value to a property it sets the value inside this box, and when you try to get the value, it will get the value stored in this box. Like in java, when we call student.getName() inside the function we return the name value, and the same with student.setName("anyName").

2. Why do we need a backing field in Kotlin? Why I can't refer directly to the property name?

class Student {
    var age: Int = 0
        get() = 2022 - age <---
        set(value) {
            age = value  <---
        }
}

Kotlin facilitates the way we call properties, so instead of calling a getter or a setter we can call directly the property by name and do whatever we want, so if I used directly the property in the getter for example like above, I'm calling the getter to get age value right? if so, the getter will see that inside it calls age again, and so on, hence an infinite recursive call will cause a StackOverflow exception.

class Student {
    var age: Int = 0
        get() = 2022 - age <--- call get() for age property
        set(value) {
            age = value  <--- call set() for age property
        }
}

To take advantage of kotlin property, and avoid StackOverFlow, kotlin introduced field modifier to refer to the property box for getting and setting values.

3. When does it get created?

if you think about the java example, you will see that, we need a local property student.name if we need to get its value inside the getter, or set a value inside the setter.

Kotlin is no different:

  • if you use at least one of the default accessors (get, set) kotlin will generate a backing field, because it needs a box to store or retrieve a value from.
private var age: Int = 27 <-- we are using the default get and set methods.
private var age: Int
    get() = 27 <-- we are using the default set method, so a backing field will be created for you.
  • if you refer to the field modifier inside a custom accessor, kotlin will generate a backing field for you.
    private val age: Int
          get() = 2022 - field
    

Conclusion:

1- backing field is like a box, get created for you to set or get value from it.

2- Kotlin will create it for you when:

  • Use at least one default accessor function (get, set).

  • Refer to the backing field using the field modifier inside accessors.

3- backing field is used to prevent the recursive call of the property accessor functions.

Peace โœŒ๏ธ

ย