Beyond plain functions, how do Kotlin interface property accessors with default bodies and methods marked @JvmStatic in interfaces interact with the DefaultImpls / -Xjvm-default mechanism?
answer
- Default getters compile like default methods
- Legacy: getX body in DefaultImpls, abstract on JVM
- all: real default getter, Java inherits
- One flag governs functions + accessors
- @JvmStatic/companion is a separate concern
basics
~20 sInterface properties with default getters follow the same rule as default methods: in legacy mode the getter body sits in the helper class; with -Xjvm-default=all it becomes a real default getter Java can inherit. The same flag governs all default members.
solid answer
~40 sA Kotlin interface property cannot have a backing field, but it can supply a **default getter** (and setter for `var`). These accessors are just methods, so they compile exactly like default functions: in legacy mode the getter/setter body lands in `Iface$DefaultImpls` (`getX($this)`), and the JVM interface accessor stays abstract; under `-Xjvm-default=all` they become real JVM `default` accessor methods inheritable by Java. The `-Xjvm-default` mode therefore governs **all** default members uniformly — functions and property accessors alike. Note `@JvmStatic` is not applicable to ordinary interface members the way it is to companion-object members; static members on interfaces live in the companion, and their JVM placement is a separate concern from DefaultImpls.
code
kotlin · 8 linesinterface Config {
val timeoutMs: Int
get() = 5000 // legacy: Config$DefaultImpls.getTimeoutMs(this); all: real default getter
companion object {
@JvmStatic fun defaults(): Config = TODO() // static interop, no DefaultImpls
}
}go deeper
May not realize property getters are compiled like methods at all.
Knows default getters exist and have no backing field, but may miss the DefaultImpls parallel.
Explains that the same -Xjvm-default strategy applies to accessors and separates @JvmStatic/companion concerns.
Reasons about the full interface ABI surface (accessors, companion statics, defaults) when designing Java-friendly Kotlin APIs.
## Default property accessors are methods Kotlin interface properties have **no backing field**, but you can provide a computed default: ```kotlin interface Config { val timeoutMs: Int get() = 5000 // default getter body } ``` The getter `getTimeoutMs()` is compiled with the *same* strategy as a default function: - **Legacy mode**: `getTimeoutMs()` is abstract on the JVM; the body lives in `Config$DefaultImpls.getTimeoutMs(Config $this)`. Java implementors must override `getTimeoutMs()`. - **`-Xjvm-default=all`**: a real JVM `default` getter is emitted; Java inherits it. For a `var` with a default setter, the same applies to `setX`. ## Why this matters for interop A Java class implementing `Config` in legacy mode is forced to implement the getter even though Kotlin code 'sees' a default. Switching the module to `all` removes that friction. So the single `-Xjvm-default` knob covers functions **and** property accessors consistently. ## Static-ish members on interfaces Kotlin places interface 'static' members in a **companion object** of the interface, not directly on it. To expose a companion function as a true JVM `static` on the interface, you use `@JvmStatic` **on the companion member** — this is orthogonal to default-method emission. There is no `DefaultImpls` involvement for companion statics; they get their own placement (a `Companion` nested class, optionally with a static bridge from `@JvmStatic`). ```kotlin interface Codec { companion object { @JvmStatic fun create(): Codec = TODO() // static interop, unrelated to DefaultImpls } } ``` ## Edge cases - A default getter that references another member calls it through `$this` in legacy mode. - Properties with **only** an abstract declaration (no `get()`) generate no DefaultImpls entry — there is no body to host. - Constant-like `const val` is not allowed on interfaces; use a companion `const val` instead, again unrelated to DefaultImpls. ## Keywords default getter/setter, no backing field, `DefaultImpls`, `-Xjvm-default=all`, `@JvmStatic`, companion object.
- Can an interface property have a backing field to store state for the default getter?No. Interface properties have no backing field; a default getter must compute its value or delegate to other (possibly abstract) members.
- Does @JvmStatic on a companion member change DefaultImpls generation?No. @JvmStatic affects how the companion member is exposed as a JVM static; it is unrelated to default-method/DefaultImpls handling.
saying these in an interview costs you the question
- Claiming interface properties can have backing fields
- Thinking accessors use a different mechanism than functions
- Believing @JvmStatic controls DefaultImpls
- Saying default getters always become real JVM default methods regardless of flag
- Confusing companion statics with DefaultImpls statics