Kotlin Properties in Depth
A property can run code each time its value is read or written. A custom getter computes the read value, and a custom setter controls each write.
A computed fahrenheit property
The fahrenheit property stores nothing of its own. Each read runs the getter, which works the value out from the current celsius value.
class Temperature(var celsius: Int) {
val fahrenheit: Int
get() = celsius * 9 / 5 + 32
}
fun main() {
val temp = Temperature(20)
println(temp.fahrenheit)
temp.celsius = 30
println(temp.fahrenheit)
}A setter that stores an uppercase value
The setter turns each new value into uppercase letters and stores the result in field. The getter wraps the stored value in brackets on each read.
class Tag {
var text: String = ""
set(value) {
field = value.uppercase()
}
get() = "[$field]"
}
fun main() {
val tag = Tag()
tag.text = "warm"
println(tag.text)
tag.text = "cold"
println(tag.text)
}Getters that read other properties
The area getter multiplies width and height on each read. The isSquare getter compares the same two properties.
class Rectangle(val width: Int, val height: Int) {
val area: Int
get() = width * height
val isSquare: Boolean
get() = width == height
}
fun main() {
val wide = Rectangle(4, 5)
println(wide.area)
println(wide.isSquare)
val even = Rectangle(3, 3)
println(even.area)
println(even.isSquare)
}Example
class Member(val name: String) {
var level: Int = 1
set(value) {
field = if (value < 1) 1 else value
}
val summary: String
get() = "$name is level $level"
}
fun main() {
val member = Member("Ana")
member.level = 0
println(member.level)
member.level = 5
println(member.summary)
}Key points
- A computed property stores nothing and works its value out in its getter on each read.
- A custom getter starts with get and returns the value for a read.
- A custom setter starts with set and receives the new value as its parameter.
- Inside an accessor, field names the stored value behind the property.
- A getter can read other properties of the same class.
- A val has a getter and no setter, while a var has both a getter and a setter.
In this example, the setter for level guards the stored value and raises any write below one up to one. The summary property is computed, and its getter reads name and level each time it runs. The first write of zero lands as one, and the summary then reports the later level of five.
Note
Writing field inside a setter stores the new value, while writing the property name there would call the setter again.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท Kotlin Playground
Exercise
What does field mean inside a custom setter?