liveBook · Manning

Accessor method

As explained in Kotlin in Action, 2E

A property accessor is a getter or setter that defines how a Kotlin property value is read or changed.

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

How Kotlin in Action, 2E covers it

How deep it goes
Explains default, computed, backing-field, visibility-controlled, interface, and reified accessors, while deferring delegated and late-initialized properties.
Examples
Demonstrates Rectangle.isSquare, interface nicknames, address-change logging, ageIn2050, LengthCounter, and a reified canonical extension property.
What it assumes
Assumes basic classes and val/var properties, then introduces custom getter syntax through progressively richer examples.
What you can do after
Build it from scratch, define getters and setters that compute values, update backing fields, and limit writes with private setters.
How it connects
Connects properties with backing fields, interfaces, member functions, extension properties, reified type parameters, and Java interoperability.

Also explained in

Compare how 13 books explain accessor method →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Kotlin in Action, 2E. The section links point to the parts of the book it draws on.