Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
August 20, 2022 12:21 am GMT

Understand Fields and Properties in Kotlin

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

This article was originally published at vtsen.hashnode.dev on Jul 30, 2022.

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.

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:

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.

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.

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:

class Person {      var name: String = "Vincent"          private set  }

Or you can also use Backing Properties. Remove the set() and change the var to val.

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.

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.

See Also


Original Link: https://dev.to/vtsen/understand-fields-and-properties-in-kotlin-2dlp

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To