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
}