skip to content

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

level: middleimportance: should knowfreq 42%

answer

  1. Top-level decls -> FileNameKt facade class
  2. Java calls UtilsKt.fn() as static
  3. @file:JvmName goes above 'package'
  4. Renames the facade, not the function
  5. Pair with @file:JvmMultifileClass to merge files

basics

~20 s

Top-level Kotlin functions and properties in a file get wrapped in an auto-generated class named after the file plus 'Kt' (e.g. Utils.kt becomes UtilsKt). @file:JvmName renames that wrapper class so Java calls it by a nicer name.

solid answer

~40 s

The JVM has no concept of free functions, so the Kotlin compiler collects all top-level functions and properties of a `.kt` file into a synthetic **facade class** whose name is the file name with a `Kt` suffix — `Utils.kt` -> `UtilsKt`. Java must call these as static methods on that class: `UtilsKt.helper()`. Placing `@file:JvmName("MyUtils")` at the very top of the file (before the package declaration, as a file-level annotation target) renames the facade to `MyUtils`, so Java writes `MyUtils.helper()`. This only affects the facade class name; Kotlin callers are unaffected since they call top-level functions directly. Combined with `@file:JvmMultifileClass`, you can even merge top-level declarations from several files into one facade with the same `@file:JvmName`.

code

kotlin · 8 lines
kotlin
@file:JvmName("TextUtils")

package com.example.text

fun slugify(s: String): String = s.lowercase().replace(' ', '-')

// Kotlin: slugify("Hello World")
// Java:   com.example.text.TextUtils.slugify("Hello World");

go deeper

for a junior

Knows top-level functions become a FileNameKt class and Java calls them statically.

for a middle

Applies @file:JvmName correctly (above package) and explains it renames only the facade.

for a senior

Distinguishes @file:JvmName from @JvmName, and uses @file:JvmMultifileClass to design clean Java-facing utility classes.

for a principal

Designs a library's Java-facing surface: chooses facade naming, multifile grouping, and stable binary names to avoid breaking Java consumers across releases.

## Why a facade class exists The JVM requires every method to live in a class. Kotlin lets you declare **top-level** functions and properties (outside any class). To make these callable on the JVM, the compiler emits a synthetic **facade class** containing them as `static` members. ## Default naming: FileNameKt The default facade name is the **source file name** with a `Kt` suffix: - `Utils.kt` -> class `UtilsKt` - `StringExtensions.kt` -> class `StringExtensionsKt` ```kotlin // file: Utils.kt package com.example fun greet(name: String) = "Hi $name" ``` From Java: ```java String s = com.example.UtilsKt.greet("Ann"); ``` From Kotlin you just call `greet("Ann")` — no class qualifier. ## Renaming with @file:JvmName The `@file:JvmName("...")` annotation uses the **file** use-site target and must appear **before the package declaration** at the top of the file: ```kotlin @file:JvmName("StringUtils") package com.example fun greet(name: String) = "Hi $name" ``` Now Java calls `com.example.StringUtils.greet("Ann")`. This is the recommended way to give Java a clean, library-style utility class name instead of the `...Kt` default. ## Merging multiple files: @file:JvmMultifileClass By default each file gets its own facade. If you want top-level declarations spread across several files to appear under **one** facade class, add **both** annotations to each file, using the same `@file:JvmName`: ```kotlin @file:JvmName("StringUtils") @file:JvmMultifileClass package com.example ``` Do this in `StringUtilsA.kt` and `StringUtilsB.kt` and Java sees a single `StringUtils` class combining both files' top-level members. ## Key rules and gotchas - `@file:JvmName` only affects the **facade class name**, not individual function names (use plain `@JvmName` for those). - It must be a **file-level** annotation (the `@file:` target) placed at the very top, above `package`. - It does not change Kotlin call syntax at all. - Without `@JvmMultifileClass`, two files declaring the same `@file:JvmName` would collide. ## Summary Top-level declarations live in a `FileNameKt` facade; `@file:JvmName` renames that facade for Java, and `@file:JvmMultifileClass` lets several files share one renamed facade.

  • Where must @file:JvmName be placed?
    At the very top of the file, before the package declaration, using the file-level annotation target @file:.
  • How do you make two files share one facade class?
    Give both files the same @file:JvmName and also annotate each with @file:JvmMultifileClass.

Top-level functions are loose papers; the facade class is the folder. @file:JvmName relabels the folder so Java can find it under a tidy name.

saying these in an interview costs you the question

  • Saying @file:JvmName renames individual functions
  • Placing the annotation after the package statement
  • Forgetting Java must qualify top-level calls with the facade class
  • Claiming the facade is named after the package, not the file
  • Not knowing @file:JvmMultifileClass exists for merging

context