In Kotlin, properties can have custom getters and setters by defining get() and/or set(value) directly under the property.
var propertyName: Type = initialValue
get() {
return field
}
set(value) {
field = value
}
field is the backing field automatically generated by Kotlin when needed.
Custom getter
class Person(
val firstName: String,
val lastName: String
) {
val fullName: String
get() = "$firstName $lastName"
}
Usage:
val person = Person("Ada", "Lovelace")
println(person.fullName) // Ada Lovelace
Here, fullName does not store a value. It is computed every time it is accessed.
Custom setter
class User {
var age: Int = 0
set(value) {
field = if (value >= 0) value else 0
}
}
Usage:
val user = User()
user.age = -5
println(user.age) // 0
The setter validates the assigned value before storing it.
Custom getter and setter together
class Temperature {
var celsius: Double = 0.0
get() = field
set(value) {
field = value.coerceAtLeast(-273.15)
}
var fahrenheit: Double
get() = celsius * 9 / 5 + 32
set(value) {
celsius = (value - 32) * 5 / 9
}
}
Usage:
val temperature = Temperature()
temperature.celsius = 100.0
println(temperature.fahrenheit) // 212.0
temperature.fahrenheit = 32.0
println(temperature.celsius) // 0.0
Important rules
valproperties can only have a custom getter, not a setter.varproperties can have both a getter and a setter.- Use
fieldinside accessors when you want to refer to the property’s backing field. - Do not write
propertyName = valueinside its own setter, because that recursively calls the setter.
For example, avoid this:
var name: String = ""
set(value) {
name = value // recursive setter call
}
Use this instead:
var name: String = ""
set(value) {
field = value
}
Example with validation
class Product {
var price: Double = 0.0
set(value) {
require(value >= 0) { "Price cannot be negative" }
field = value
}
}
val product = Product()
product.price = 19.99
println(product.price)
// product.price = -1.0
// Throws IllegalArgumentException: Price cannot be negative
So the basic pattern is:
var myProperty: String = ""
get() = field
set(value) {
field = value.trim()
}
