Understand Fields and Properties in Kotlin
Tags: android, kotlin, beginners
Published: 2022-08-20 00:21:28

**How Kotlin implicitly implements field, getter and setter function for you when you declare a property?**

Properties and fields terminologies in Kotlin sometimes is a bit confusing because technically, Kotlin doesn't have Fields. You can't declare a field. Everything is Properties!

However, to avoid confusion, I prefer to define Fields and Properties separately based on the following:  
- **Fields** are private member variables of a class. Memory is allocated.
- **Properties** are public or protected getter or setter functions which allow you to access to the private fields.

> I like to define like this because it helps my understanding and it also makes things a lot easier to explain.

## Implicit Field, Implicit Getter/Setter
Let's look at this example. `name` is a property.  
```kotlin
class Person {
    var name = "Vincent"
}
```
When you declare a property like this, Kotlin implicitly creates field, getter and setter functions for you. 

In Java decompiled code, it looks like this:

```java
public final class Person {
   @NotNull
   private String name = "Vincent";

   @NotNull
   public final String getName() {
      return this.name;
   }

   public final void setName(@NotNull String var1) {
      Intrinsics.checkNotNullParameter(var1, "<set-?>");
      this.name = var1;
   }
}
```
As you can see, `private String name` is the field (member variable). `getName()` and `setName()` are the property getter and setter functions (also known as property accessors)

## Implicit Field, Explicit Getter/Setter
Of course, you can also explicitly define the property getter and setter functions, which also generates a very similar decompiled Java code. 
```kotlin
class Person {
    var name: String = "Vincent"
        get() { return field }
        set(value) { field = value }
}
```
`field` is implicitly created here, which is also called **Backing Fields**. Providing property accessors (i.e. `get()` and `set()`) to the property is called **Backing Properties**. 

## Explicit Field, Explicit Getter/Setter
You can explicitly define Field too. Basically everything is explicit now.
```kotlin
class Person {  
    private var _name:String = "Vincent"  
    var name: String  
        get() { return _name }  
        set(value) { _name = value }  
}
```
> Instead of implicit `field`, `_name` is the explicit field here.

## Private Set or Backing Properties?
Now, you want the property `name` to be read only outside the class.  So you can restrict the property setter using `private set`.  

For example:
```kotlin
class Person {  
    var name: String = "Vincent"  
        private set  
}
```
Or you can also use Backing Properties. Remove the `set()` and change the `var` to `val`.
```kotlin
class Person {  
    private var _name:String = "Vincent"  
    val name: String  
        get() { return _name }  
}
```

Both of the code generate the same decompile Java code as below. Please note, the `setName()` function removed.
```Java
public final class Person {  
   @NotNull  
   private String name = "Vincent";  
  
  @NotNull  
   public final String getName() {  
      return this.name;  
  }  
}
```
I personally prefer `private set` because it has less code. 

## Misuse of private set
But wait, not so fast. What if you convert the following backing property

```
class MainViewModel: ViewModel() {
    private val _state: MutableState<Int?> = mutableStateOf(null)
    val state: State<Int?> = _state
    /*...*/
}
```
 to `private set`
```
class MainViewModel: ViewModel() {
    var state: MutableState<Int?> = mutableStateOf(null)
        private set
}
```

This is a very good example of misusing the `private set`. What it really means is you can't assign a new variable to `state` outside the `MainViewModel` class. The `state` variable itself is still mutable (which means you can modify its value). 

The backing property above exposes only the read only `State`, changing it to `private set` defeats its original purpose.  So, in this scenario, you don't use the `private set`. This applies to any mutable data.


## Conclusion
I think it is important to understand the fields and properties concepts here. 

When you declare a property, it doesn't allocate a new memory because it is merely a getter or setter function. However, if implicit field implementation is inferred (like code examples above), then yes, it takes up the memory allocation. 

Finally, don't convert every backing property to `private set`. You shouldn't do that, especially your data is mutable. 

---

*Originally published at [https://vtsen.hashnode.dev](https://vtsen.hashnode.dev/understand-fields-and-properties-in-kotlin)*.