What is the FooKt facade class for top-level Kotlin declarations, and how does @file:JvmName change it?
answer
- Top-level decls -> FileNameKt facade class
- Java calls UtilsKt.fn() as static
- @file:JvmName goes above 'package'
- Renames the facade, not the function
- Pair with @file:JvmMultifileClass to merge files
basics
~20 sTop-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 sThe 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@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
Knows top-level functions become a FileNameKt class and Java calls them statically.
Applies @file:JvmName correctly (above package) and explains it renames only the facade.
Distinguishes @file:JvmName from @JvmName, and uses @file:JvmMultifileClass to design clean Java-facing utility classes.
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