How do you rename a Kotlin property's getter or setter for Java callers using @JvmName, and what subtleties come with property accessors?
answer
- Property -> getX()/setX() on JVM
- @get:JvmName / @set:JvmName use-site targets
- Or @JvmName on an explicit get()/set() block
- Renaming breaks JavaBean introspection
- Kotlin access unchanged; bytecode names change
basics
~10 sProperties compile to getX()/setX() methods. You can use @get:JvmName and @set:JvmName to rename those generated methods for Java, while Kotlin still accesses the property normally.
solid answer
~40 sA Kotlin property generates JVM accessor methods: `val x` -> `getX()`, `var x` -> `getX()`/`setX()` (and `is`-prefixed booleans keep the `is` name). To rename what Java sees, apply `@JvmName` with a **use-site target** on the accessor: `@get:JvmName("...")` and `@set:JvmName("...")`. You can place these on the property declaration. Kotlin callers still read/write the property by its name; only the bytecode accessor names change. Subtleties: (1) renaming a getter so it no longer follows the `getX` convention means Java won't treat it as a JavaBean property; (2) for a `var`, you typically rename both accessors consistently; (3) explicit accessor blocks can also carry `@JvmName`; (4) for top-level/extension properties and erasure-style clashes among properties, the accessor-targeted `@JvmName` is the same fix as for functions.
code
kotlin · 8 linesclass Config {
@get:JvmName("resolveTimeout")
@set:JvmName("applyTimeout")
var timeoutMs: Long = 5000
}
// Java: config.applyTimeout(10000); long t = config.resolveTimeout();
// Kotlin: config.timeoutMs = 10000; val t = config.timeoutMsgo deeper
Knows properties become getX()/setX() and that getters can be renamed for Java.
Correctly uses @get:JvmName/@set:JvmName with use-site targets and knows Kotlin access is unaffected.
Anticipates JavaBean-introspection breakage, handles var getter/setter consistency, and annotates explicit accessor blocks.
Sets a team policy on accessor renaming, balancing Java ergonomics against framework/serialization compatibility and binary stability.
## Properties become accessor methods on the JVM Kotlin properties are not fields to Java by default — they compile to **getter/setter methods**: - `val name: String` -> `String getName()` - `var count: Int` -> `int getCount()` and `void setCount(int)` - A boolean-ish property named `isActive` keeps `isActive()` (no double `is`). ## Renaming accessors with use-site targets To change the **Java-visible accessor name**, annotate the property with a use-site-targeted `@JvmName`: ```kotlin class User(name: String) { @get:JvmName("fetchName") val name: String = name @get:JvmName("computedAge") @set:JvmName("updateAge") var age: Int = 0 } ``` - `@get:JvmName` renames the getter. - `@set:JvmName` renames the setter (only valid on a `var`). From Java: `user.fetchName()`, `user.computedAge()`, `user.updateAge(30)`. From Kotlin: still `user.name`, `user.age`, `user.age = 30`. ## You can also annotate explicit accessors ```kotlin val slug: String @JvmName("slugValue") get() = computeSlug() ``` Here `@JvmName` sits directly on the `get()` accessor; no use-site target is needed because it is already on the accessor. ## Subtleties and gotchas - **Breaks JavaBean convention:** if you rename a getter away from the `getX`/`isX` pattern, frameworks that rely on bean introspection (some serializers, older reflection-based libraries) will no longer recognize it as a property. Use this deliberately. - **var consistency:** for a `var`, decide whether you rename only the getter, only the setter, or both — mismatched names can confuse Java consumers. - **Boolean `is`-prefix:** Kotlin already maps `isX` properly; don't fight it unless you have a reason. - **Erasure clashes among properties:** two extension properties whose erased accessor signatures collide can be separated with `@get:JvmName`, exactly like the function case. - **No effect on Kotlin:** all renames are bytecode-only. ## Summary Properties expose getter/setter methods to Java; `@get:JvmName` / `@set:JvmName` (or `@JvmName` on an explicit accessor block) rename them, with the caveat that you may break bean-style introspection.
- What can break if you rename a getter away from the getX convention?Bean-introspection-based tools (some serializers, reflective frameworks) won't recognize it as a property anymore, since they look for getX/isX accessors.
- How do you rename a setter, and when is it invalid?Use @set:JvmName. It's only valid on a var (a val has no setter).
saying these in an interview costs you the question
- Putting plain @JvmName on the property and expecting it to rename the getter without a use-site target
- Using @set:JvmName on a val
- Ignoring the JavaBean-introspection breakage
- Claiming Kotlin property access also changes
- Thinking properties are exposed to Java as raw fields by default