Properties and fields terminologies in Kotlin typically is a bit complicated as a result of technically, Kotlin does not have Fields. You may’t declare a discipline. Every part is Properties!
Nonetheless, to keep away from confusion, I desire to outline Fields and Properties individually based mostly on the next:
- Fields are non-public member variables of a category. Reminiscence is allotted.
- Properties are public or protected getter or setter features which let you entry to the non-public fields.
I wish to outline like this as a result of it helps my understanding and it additionally makes issues lots simpler to clarify.
Implicit Discipline, Implicit Getter/Setter
Let us take a look at this instance. title
is a property.
class Particular person {
var title = "Vincent"
}
If you declare a property like this, Kotlin implicitly creates discipline, getter and setter features for you.
In Java decompiled code, it appears to be like like this:
public ultimate class Particular person {
@NotNull
non-public String title = "Vincent";
@NotNull
public ultimate String getName() {
return this.title;
}
public ultimate void setName(@NotNull String var1) {
Intrinsics.checkNotNullParameter(var1, "<set-?>");
this.title = var1;
}
}
As you possibly can see, non-public String title
is the sector (member variable). getName()
and setName()
are the property getter and setter features (also called property accessors)
Implicit Discipline, Express Getter/Setter
After all, it’s also possible to explicitly outline the property getter and setter features, which additionally generates a really related decompiled Java code.
class Particular person {
var title: String = "Vincent"
get() { return discipline }
set(worth) { discipline = worth }
}
discipline
is implicitly created right here, which can be referred to as Backing Fields. Offering property accessors (i.e. get()
and set()
) to the property known as Backing Properties.
Express Discipline, Express Getter/Setter
You may explicitly outline Discipline too. Mainly all the things is express now.
class Particular person {
non-public var _name:String = "Vincent"
var title: String
get() { return _name }
set(worth) { _name = worth }
}
As a substitute of implicit
discipline
,_name
is the specific discipline right here.
Personal Set or Backing Properties?
Now, you need the property title
to be learn solely outdoors the category. So you possibly can limit the property setter utilizing non-public set
.
For instance:
class Particular person {
var title: String = "Vincent"
non-public set
}
Or it’s also possible to use Backing Properties. Take away the set()
and alter the var
to val
.
class Particular person {
non-public var _name:String = "Vincent"
val title: String
get() { return _name }
}
Each of the code generate the identical decompile Java code as under. Please observe, the setName()
operate eliminated.
public ultimate class Particular person {
@NotNull
non-public String title = "Vincent";
@NotNull
public ultimate String getName() {
return this.title;
}
}
I personally desire non-public set
as a result of it has much less code.
Misuse of personal set
However wait, not so quick. What in the event you convert the next backing property
class MainViewModel: ViewModel() {
non-public val _state: MutableState<Int?> = mutableStateOf(null)
val state: State<Int?> = _state
}
to non-public set
class MainViewModel: ViewModel() {
var state: MutableState<Int?> = mutableStateOf(null)
non-public set
}
It is a excellent instance of misusing the non-public set
. What it actually means is you possibly can’t assign a brand new variable to state
outdoors the MainViewModel
class. The state
variable itself remains to be mutable (which implies you possibly can modify its worth).
The backing property above exposes solely the learn solely State
, altering it to non-public set
defeats its authentic function. So, on this state of affairs, you do not use the non-public set
. This is applicable to any mutable knowledge.
Conclusion
I feel you will need to perceive the fields and properties ideas right here.
If you declare a property, it does not allocate a brand new reminiscence as a result of it’s merely a getter or setter operate. Nonetheless, if implicit discipline implementation is inferred (like code examples above), then sure, it takes up the reminiscence allocation.
Lastly, do not convert each backing property to non-public set
. You should not try this, particularly your knowledge is mutable.