An accessor defines how a Kotlin property is read or changed. A val has a getter; a var has both a getter and setter. Default accessors read and update stored state, preserving Kotlin’s concise property syntax while exposing conventional getter and setter methods to Java. section 2.2.1
Compute a property on demand
Use a custom getter when a value is a characteristic derived from other state rather than information that must be stored. class Rectangle(val height: Int, val width: Int) { val isSquare: Boolean get() = height == width } rectangle.isSquare still looks like property access. Prefer a property for a class characteristic; prefer a member function for behavior. section 2.2.2
Custom accessors support several common designs:
- Add work around a stored value. A setter can log or validate a change, then assign the backing field with field = value. section 4.2.4
- Avoid stored state entirely. If custom accessors do not use field, Kotlin need not generate a backing field; a getter and setter can derive ageIn2050 from birthYear. section 4.2.4
- Restrict mutation without hiding reads. Keep a property public and declare private set so only class code can maintain its invariant. section 4.2.5
- Implement interface properties differently. A getter can derive nickname from email on every access, whereas an initializer can compute and store it once. section 4.2.3
- Use inline reified extension-property accessors when an accessor needs the concrete generic type, such as returning a canonical class name. section 11.2.4
Listing 4.20 Accessing the backing field in a setter
class User(val name: String) {
var address: String = "unspecified"
set(value: String) {
println(
"""
Address was changed for $name:
"$field" -> "$value". #1
""".trimIndent()
)
field = value #2
}
}
fun main() {
val user = User("Alice")
user.address = "Christoph-Rapparini-Bogen 23"
// Address was changed for Alice:
// "unspecified" -> "Christoph-Rapparini-Bogen 23".
}
The setter reads the old backing-field value for logging and then writes the replacement value, while callers continue using ordinary property assignment. section 4.2.4
From Java, Kotlin properties retain accessor-based interoperability: name is available through getName(), and a mutable Boolean property can be read with isStudent() and changed with setStudent(). Kotlin callers use person.name and person.isStudent = false instead. section 2.2.1












