What is the generated 'facade' class for top-level Kotlin functions, and how does @file:JvmName change it?
answer
- Top-level funcs → synthetic facade class
- Default name = FileName + 'Kt'
- @file:JvmName renames the facade
- Annotation goes ABOVE package
- @JvmMultifileClass merges files into one facade
basics
~10 sTop-level Kotlin functions and extensions compile into a hidden class named after the file (e.g. Utils.kt becomes UtilsKt). @file:JvmName lets you rename that class so Java code calling it sees a nicer name.
solid answer
~30 sKotlin has no free-floating functions on the JVM, so every top-level function/property in a file is placed as a static member on a synthetic **facade class** whose default name is the file name plus `Kt` (e.g. `StringUtils.kt` → `StringUtilsKt`). Java callers must reference that class: `StringUtilsKt.shout("hi")`. The `@file:JvmName("StringUtils")` annotation (placed at the very top, before `package`) renames the facade so Java sees `StringUtils.shout("hi")`. You can also merge multiple files into one facade with `@file:JvmMultifileClass` combined with the same `@JvmName`. This only matters for **Java interop**; Kotlin callers never name the facade — they import the function symbol directly.
code
kotlin · 6 lines@file:JvmName("Strings")
@file:JvmMultifileClass
package com.app
fun shout(s: String) = s.uppercase() + "!"
// Java: Strings.shout("hi")go deeper
Knows top-level functions become static members of a FileNameKt class.
Explains the default naming rule and uses @file:JvmName to rename the facade for Java.
Adds @JvmMultifileClass merging and flags binary-compat impact of renaming the facade.
Treats facade naming as part of a published Java-facing API surface, managing it for stability/deprecation across module boundaries.
## Why a facade exists The JVM has **no top-level functions** — every method must live in a class. So when Kotlin compiles `StringUtils.kt` containing top-level `fun shout(...)`, it emits a synthetic **facade class** holding those functions as `public static` methods. ## Default name The facade name is the **file name with `Kt` appended**: - `StringUtils.kt` → class `StringUtilsKt` - `Main.kt` → class `MainKt` (this is why a `main` entrypoint is `MainKt`). ## Calling from Java ```java // default facade name String s = StringUtilsKt.shout("hi"); ``` ## Renaming with @file:JvmName Put the annotation as a **file-level annotation** at the very top, above the `package` statement: ```kotlin @file:JvmName("StringUtils") package com.app fun shout(s: String) = s.uppercase() + "!" ``` Now Java calls: ```java String s = StringUtils.shout("hi"); ``` ## Merging files: @JvmMultifileClass By default each file gets its own facade. To expose several files under **one** Java class name, add `@file:JvmMultifileClass` plus the **same** `@file:JvmName` in each file: ```kotlin @file:JvmName("Strings") @file:JvmMultifileClass package com.app ``` All such files contribute their statics to one `Strings` facade. ## Scope of effect This is **purely a Java-interop concern**. Kotlin call sites import the function by name and never mention the facade. Renaming the facade does not change Kotlin source at all. ## Gotchas - `@file:JvmName` must precede `package`. - Without `@JvmMultifileClass`, two files declaring the same `@JvmName` cause a duplicate-class compile error. - Renaming the facade is a **binary-incompatible** change for existing Java callers compiled against the old name.
- Where exactly must @file:JvmName be placed?As a file-level annotation at the very top of the file, before the package declaration.
- How do you expose top-level functions from two files under one Java class?Give both files the same @file:JvmName and add @file:JvmMultifileClass to each.
The facade is like a mailbox the file's functions are stuffed into; @file:JvmName just relabels the mailbox so the Java postman finds it under a friendlier name.
saying these in an interview costs you the question
- Thinks top-level functions can be called without any class from Java
- Places @file:JvmName below the package statement
- Says the facade name is just the file name without the 'Kt' suffix
- Believes @file:JvmName affects Kotlin call sites