Recursive Property Accessor

ID

kotlin.recursive_property_accessor

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Kotlin

Tags

best-practice, reliability

Description

Reports custom property accessors (get() or set()) that reference their own property name. In Kotlin, mentioning the property name inside its own accessor body does not read or write the backing field — it dispatches through the accessor itself, causing an infinite recursion and a StackOverflowError the first time the accessor is invoked.

Rationale

class Bad {
    val foo: Int
        get() = foo                  // FLAW — recurses on get

    var bar: Int = 0
        get() = bar                  // FLAW
        set(value) { bar = value }   // FLAW — recurses on set
}

This is a particularly painful bug class because the accessor compiles cleanly: the language does not warn about the self-reference. The crash appears at runtime the first time anyone touches the property — often in a production code path that wasn’t exercised in unit tests.

Remediation

Use the implicit field identifier inside the accessor body. field addresses the backing field directly and bypasses the accessor:

class Good {
    var bar: Int = 0
        get() = field
        set(value) { field = value }
}

If the accessor needs to delegate to something other than the field — for example a method on the same class — name that delegate explicitly:

class GoodDelegate {
    val foo: Int
        get() = computeFoo()

    private fun computeFoo(): Int = 42
}