skip to content

What is the generated 'facade' class for top-level Kotlin functions, and how does @file:JvmName change it?

level: middleimportance: should knowfreq 55%

answer

  1. Top-level funcs → synthetic facade class
  2. Default name = FileName + 'Kt'
  3. @file:JvmName renames the facade
  4. Annotation goes ABOVE package
  5. @JvmMultifileClass merges files into one facade

basics

~10 s

Top-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 s

Kotlin 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
kotlin
@file:JvmName("Strings")
@file:JvmMultifileClass
package com.app

fun shout(s: String) = s.uppercase() + "!"
// Java: Strings.shout("hi")

go deeper

for a junior

Knows top-level functions become static members of a FileNameKt class.

for a middle

Explains the default naming rule and uses @file:JvmName to rename the facade for Java.

for a senior

Adds @JvmMultifileClass merging and flags binary-compat impact of renaming the facade.

for a principal

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

context