skip to content

What does the @JvmName annotation do, and why would you put it on a Kotlin function or property accessor that Java code will call?

level: juniorimportance: must knowfreq 55%

answer

  1. Renames the JVM/bytecode method name
  2. kotlin.jvm package annotation
  3. Java sees new name, Kotlin still uses old name
  4. Fixes nicer-Java-API and erasure clashes
  5. Works on functions and getter/setter

basics

~20 s

@JvmName changes the name that a Kotlin function, getter, or setter shows up as when called from Java. It lets you give Java a nicer name or avoid a name conflict, without changing the Kotlin name.

solid answer

~40 s

@JvmName is a compile-time annotation that overrides the method name emitted into the JVM bytecode for a function or a property accessor (getter/setter). Kotlin code keeps calling it by its original Kotlin name; Java callers see the overridden name. The two main uses: (1) make the Java-facing API read naturally, e.g. annotate a Kotlin getter so Java sees getX() with a custom name, or rename a function whose Kotlin name relies on Kotlin-only features; (2) resolve JVM signature clashes caused by type erasure (two Kotlin functions that differ only in generic type erase to the same JVM signature). It has no effect on Kotlin-to-Kotlin calls and is purely an interop/bytecode-naming tool.

code

kotlin · 7 lines
kotlin
class Money(val cents: Long) {
    @JvmName("toDollars")
    fun asDollars(): Double = cents / 100.0
}

// Kotlin:  money.asDollars()
// Java:    money.toDollars();

go deeper

for a junior

Knows @JvmName renames the Java-visible method name and that the Kotlin name is unchanged.

for a middle

Can name both use cases (nicer Java API, erasure clash) and place it on accessors with @get:/@set: targets.

for a senior

Explains it as a pure bytecode-naming compile-time tool, and reasons about its interaction with property accessors and facades.

for a principal

Frames it within an interop API-design strategy: when to expose renamed names vs. restructure the Kotlin API, and the maintenance cost of dual names.

## What @JvmName is `@JvmName` is a Kotlin annotation that lives in the `kotlin.jvm` package. It controls the **name written into the compiled `.class` file (bytecode)** for the element it annotates. It is read at compile time and erased afterward — it changes nothing at the Kotlin source level. ## What it changes vs. what it does not - **Changes:** the JVM-visible name of a function, or of a property's generated **getter/setter** methods. This is what Java callers and reflection see. - **Does NOT change:** how you call the element from Kotlin. In Kotlin you still use the original declared name. ```kotlin class Account(val ownerName: String) { @JvmName("computeBalance") fun balance(): Long = 0L } ``` From Kotlin you call `account.balance()`. From Java you call `account.computeBalance()`. ## Why you need it Two big reasons: 1. **Nicer Java-facing API.** Kotlin idioms (like a function named `balance`) may not match Java conventions; renaming gives Java a clearer call site. 2. **Avoiding JVM signature clashes.** The JVM erases generics, so two Kotlin functions with the same name that differ only in a generic type parameter compile to the **same** JVM signature, which is illegal. `@JvmName` on one of them produces distinct bytecode names so both can coexist. ```kotlin // Without @JvmName these clash on the JVM (both erase to filterValid(List)): fun List<String>.filterValid(): List<String> = filter { it.isNotBlank() } @JvmName("filterValidInts") fun List<Int>.filterValid(): List<Int> = filter { it > 0 } ``` ## Where you can put it - On a **function** (member or top-level/extension). - On a **property accessor** via a use-site target: `@get:JvmName("...")` or `@set:JvmName("...")`. - On a **file** as `@file:JvmName("...")` to rename the synthetic facade class that holds top-level declarations. The annotation does nothing for Kotlin-only consumers; it exists purely to shape the bytecode for the JVM and for Java interop.

  • Does @JvmName change how you call the function from Kotlin?
    No. Kotlin callers always use the original declared name; only the JVM bytecode name (what Java/reflection sees) changes.
  • Is @JvmName a runtime or compile-time mechanism?
    Compile-time. It instructs the Kotlin compiler what name to emit into the class file; there is no runtime behavior.

Like a stage name: the actor (Kotlin) is still called by their real name internally, but the audience (Java) sees the name on the marquee.

saying these in an interview costs you the question

  • Claiming it renames the Kotlin-visible name too
  • Thinking it has any runtime/reflection-injection behavior beyond the emitted name
  • Saying it works only on top-level functions
  • Confusing it with @JvmStatic or @JvmField
  • Believing it affects Kotlin-to-Kotlin calls

context