How and why would you use `@get:JvmName` (and `@set:JvmName`) on a Kotlin property, and what problem does it solve at the Java boundary?
answer
- @JvmName renames the bytecode method, not the Kotlin name
- On properties: must pick @get: or @set:
- Fixes is-prefix Boolean accessor names
- Resolves platform/signature clashes
- Kotlin call sites unchanged
basics
~10 s@get:JvmName("...") renames the getter method that Java sees, without changing the Kotlin property name. You use it to fix or customize the Java-facing accessor name, e.g. to avoid awkward or clashing generated names.
solid answer
~40 s`@JvmName` renames a generated JVM method. Because a property has separate getter and setter methods, you must target the right one: `@get:JvmName("...")` renames the getter, `@set:JvmName("...")` renames the setter. Common uses: giving Java a cleaner accessor name; working around Kotlin's `is`-prefix getter rule (a `Boolean` `val isReady` generates `isReady()` not `getIsReady()`) when you need a specific name; and resolving accessor naming that would otherwise be unidiomatic for Java callers. It does **not** change how Kotlin code refers to the property. A related use is breaking a JVM signature clash where two declarations would erase to the same method name. Note `@JvmName` on the *getter* changes only the method Java calls; Kotlin still uses `obj.property`.
code
kotlin · 8 linesclass Session {
var active: Boolean = false
@get:JvmName("isSessionActive")
@set:JvmName("setSessionActive")
set(v) { field = v }
}
// Java: session.isSessionActive(); session.setSessionActive(true);
// Kotlin: session.active = truego deeper
Knows @get:JvmName renames the Java-visible getter and that the Kotlin name stays the same.
Correctly targets getter vs setter and cites the Boolean is-prefix and cleaner-accessor use cases.
Uses it to resolve platform signature clashes and understands override/identifier constraints.
Weighs JVM-API stability and naming conventions across a public library boundary when prescribing @JvmName usage.
## What `@JvmName` does `@JvmName("newName")` controls the **name of the method emitted into bytecode**. It does not rename the Kotlin declaration — Kotlin source still uses the original property/function name. It exists purely to shape what **Java (and other JVM languages) see**. ## Why it needs a use-site target on properties A property has more than one generated method (getter, setter), so `@JvmName` placed bare on the property is **not allowed** there in a meaningful way — you must say *which* accessor: ```kotlin var status: String = "" @get:JvmName("fetchStatus") @set:JvmName("updateStatus") set(value) { field = value.trim() } ``` From Java this is `obj.fetchStatus()` / `obj.updateStatus(...)`. From Kotlin it stays `obj.status`. ## Problems it solves at the boundary ### 1. Cleaner Java accessor names Kotlin generates `getFoo()`/`setFoo()`. If Java consumers expect a different name (matching an interface or legacy convention), `@get:JvmName` lets you supply it without renaming the property. ### 2. The `is`-prefix rule for Booleans A `Boolean` property named `isReady` generates `isReady()` (no `get`) and `setReady(...)`. If you need a non-standard accessor name for Java, `@get:JvmName`/`@set:JvmName` override the generated names. ### 3. Signature clashes Two declarations can erase to the **same JVM signature** (e.g. an extension and a member, or two functions differing only by generic erasure), producing a *platform declaration clash*. `@JvmName` on one of them gives it a distinct bytecode name so both can coexist. On properties you apply it via `@get:`/`@set:`. ```kotlin fun List<String>.firstChar(): Char = first()[0] @JvmName("firstCharInt") fun List<Int>.firstChar(): Int = first() ``` ## Key constraints - The new name must be a valid JVM identifier. - It changes **only** the JVM-visible method name; Kotlin call sites are unaffected. - Overriding a method while renaming it via `@JvmName` is restricted — you generally cannot `@JvmName` an `open`/`override` accessor in a way that breaks the override contract.
- Why can't you just put `@JvmName` directly on the property without a target?A property generates multiple methods (getter/setter), so the compiler needs `@get:`/`@set:` to know which method to rename; an untargeted `@JvmName` on a property isn't valid for this purpose.
- Does `@get:JvmName` affect Kotlin reflection or call syntax?No. Kotlin still accesses the property by its declared name; only the JVM method name (what Java/bytecode sees) changes.
saying these in an interview costs you the question
- Thinking @JvmName renames the Kotlin property too
- Putting bare @JvmName on a property and expecting it to work
- Using it to rename an override in a way that breaks the contract
- Confusing @JvmName with @JvmStatic or @JvmField