Hi, I hope everyone is doing good. Today, we will discuss one most confusing topics for me in Kotlin: Kotlin doesn’t have fields. Instead, they have only properties. It’s time to discuss first what is field and what is property.
Field Vs Property:
As I already told you, we don’t have fields in Kotlin, so that we will take some help from our old friend JAVA.
By the way, If you do Google, you will get different definitions of fields and properties, but here I am going what will help us to learn the Kotlin Properties concept.
In the above code, we can say all privateAge, protectedAge, and publicAge are fields. So they can save value in memory.
In the above code, privateAge is a property because that has getter and setter methods. So what we are saying is fields are simple values, and if any field exposes by getter and setters is called property. You can disagree with my definitions, but to the sake of Kotlin, our definition is any field with getter or getter and setter that is a property.
Now, In Kotlin, no one can create a field because everything in Kotlin is a property. The only difference or confusion is Kotlin does a lot of things at an abstract level.
No Fields only Properties:
One more point in Kotlin when we declare something with val, it means read-only, and when we use var it means read-write.
In the above code, we created a Person class in Kotlin with a property age which is read-write. If I think from the Java perspective, I will not say that it is a field and not a property, but Kotlin claims this age is a property because Kotlin doesn’t have fields. Sit tight, we are going to convert the above Kotlin code into Java, and then we will see what this.
Wow, so Kotlin is right under the hood. They created an age as a property.
In the above code, we are using a Person object in Kotlin, and now I hope things are clear when Kotlin will call setter under the hood and when getter.
We converted our Kotlin code to Java in the above code, and you can confirm Kotlin is right.
I hope until now we are clear in Kotlin the syntax looks like a Java field, but everything is a property. Next, we can discuss some more things about properties in Kotlin.
How to Control Visibility Of Getter and Setter:
As we say in the above Kotlin examples
person.age = 10 always invoke a setter method and
person.age always invoke a getter method. If we want don’t expose the setter method then we have a special syntax.
In the above code, we make the setter method private, and we can see an error in the main method. We can do the same thing with getter.
Assume we want if anyone tries to set age less than zero we should update the original value to zero and ignore the below zero value. Now, if we try to achieve this in Kotlin and if you are coming from Java maybe you will be stuck with one issue.
There is a big issue with the above code. If you remember, we discussed whenever someone called person.age = 10 or age = 10 under the hood, that is going to call a setter method. According to our definition above code will throw a StackOverflow Exception because if-else is trying to update the value of age, which under the hood invoke a setter method. Due to that, we are in infinite recursive calls. To make it more precise, we can see the above code in Java conversion.
I hope the above code makes everything clear. To handle this scenario, Kotlin gives us a new concept of the Backing field. I don’t know what his official definition is. Still, I always remember that there is always a risk of infinite recursion anywhere I want to update property inside of a setter. To resolve the recursion issue, we can access an alias by automatically using a keyword field generated by the kotlin inside setter methods.
In the above code, the field is a keyword that we refer to as a Backing filed and when we use this there will be no recursion.
In the above code, we can see there is no extra variable with the name field. So there is no additional memory usage, and Kotlin resolves the issue of infinite recursion.
Most of the time, in the database, we don’t save values like age; instead, if I have a birthdate, I can compute a person’s age at the runtime. We can do something in Kotlin by using a custom getter.
In the above code, age is a read-only computed value, which we calculate from the birth year every time someone invokes person.age.
This is something crazier than Backing Field :). Those working in Android development use this concept a lot when working with LiveData API in ViewModels. Still, to make this thing for everyone and not for Android-specific, we say every time some invoke
person.age // getter we always return an age + 1.
In the above code, we are returning a
field + 1. It means the output of the above code will be 16 and not 15. Now there is a new requirement. We want to calculate something using age, but we want the actual age and not with +1.
In the above code, the
calculateSomething will always use age+1 because we know when we invoke age, that is always called a getter method. We can resolve by doing -1 🙂 but here I make this scene so we can learn about Backing Properties. So here, backing properties will come to save us. To make sure everything works as expected, I will remove the backing property and say to Kotlin now that I will take care of it by using backing properties. Which means we will have our backing property.
As you can see in the above code, there is no more field keyword. Instead, we created our backing filed with _age name. This will resolve all of our issues. Here underscore is a convention you can give any name but Kotlin documentation prefers to use underscore with Backing Properties. The next question is maybe are we abusing a memory because now I have two Int variables. To make sure this we can convert Kotlin code to Java and review it.
Excellent, so there is no age variable under the hood :).
Thank you for reading the article. I will meet you again in the next article. BYEby