A Kotlin file Utils.kt declares a top-level function fun greet(): String. How does Java call it, and where does that method actually live on the JVM?
answer
- File name + 'Kt' = facade class
- Utils.kt -> UtilsKt.greet()
- @file:JvmName renames the facade
- @file:JvmMultifileClass merges files
- Properties become getters; const = static final
basics
~10 sKotlin puts top-level functions into an auto-generated class named after the file plus 'Kt'. So Utils.kt's greet() is called from Java as UtilsKt.greet().
solid answer
~30 sTop-level (file-level) Kotlin functions and properties have no enclosing class, but the JVM requires every method to live in a class. The compiler generates a synthetic 'file facade' class named `<FileName>Kt` — for `Utils.kt` that's `UtilsKt`. The function becomes a public static method on it, so Java calls `UtilsKt.greet()`. You can override the generated name with `@file:JvmName("Greetings")` at the top of the file, making it `Greetings.greet()`. Multiple files can merge into one facade with `@file:JvmMultifileClass` plus a shared `@file:JvmName`. From Kotlin you just call `greet()`; the facade is invisible there.
code
kotlin · 8 lines@file:JvmName("Greetings")
package com.acme
fun greet(): String = "hi"
const val VERSION = "1.0"
// Java:
// Greetings.greet(); // facade renamed
// Greetings.VERSION; // const -> static finalgo deeper
Knows top-level functions live on a FileNameKt facade and calls UtilsKt.greet().
Explains the naming rule, getter generation for properties, and @file:JvmName renaming.
Uses @file:JvmMultifileClass to design a clean, stable Java-facing utility surface across files.
Standardizes facade naming/merging across modules so renames don't break downstream Java binary compatibility.
## The problem the facade solves Kotlin allows **top-level declarations** — functions and properties written directly in a file, not inside any class. The JVM has no concept of a method outside a class, so the Kotlin compiler must put them somewhere. ## The FooKt facade class For a file `Utils.kt`, the compiler generates a `final class UtilsKt` (the **file facade**) and emits each top-level function as a `public static` method: ```kotlin // Utils.kt fun greet(): String = "hi" val VERSION = "1.0" ``` From Java: ```java String s = UtilsKt.greet(); String v = UtilsKt.getVERSION(); // property -> getter ``` The naming rule: **file name + `Kt` suffix**, with the first letter capitalized. `string-helpers.kt` becomes `StringHelpersKt`. ## Renaming the facade: @file:JvmName The `Kt` suffix is ugly for Java consumers. Put a file-level annotation at the very top (before `package`): ```kotlin @file:JvmName("Greetings") package com.acme fun greet(): String = "hi" ``` Now Java calls `Greetings.greet()`. ## Merging files: @file:JvmMultifileClass To spread one Java-facing class across several `.kt` files, give them the SAME `@file:JvmName` and add `@file:JvmMultifileClass` to each. The compiler merges them into one facade. ## Top-level properties - A normal `val`/`var` becomes a static field with a getter (and setter for `var`): `getVERSION()`. - A `const val` becomes a public static final field accessible directly as `UtilsKt.VERSION` (no getter). - `@JvmField` on a non-const top-level property exposes the field directly too. ## Key terms - **top-level declaration**: a function/property outside any class. - **file facade / `FooKt`**: the synthetic class holding those members for the JVM. - **`@file:JvmName`**: renames the facade class. - **`@file:JvmMultifileClass`**: merges multiple files into one facade.
- How does Java call a top-level `const val MAX = 10`?As a static final field: `UtilsKt.MAX` (or the renamed facade). No getter is generated for const.
- What if two files need to share one Java class name?Give both the same `@file:JvmName` and add `@file:JvmMultifileClass` to each; they merge into one facade.
Top-level functions are homeless on the JVM, so the compiler builds them a house called FooKt and moves them in as static residents.
saying these in an interview costs you the question
- Saying top-level functions are global statics with no class
- Forgetting the 'Kt' suffix or the capitalization rule
- Putting @file:JvmName after the package declaration
- Assuming Java sees the function in the package scope directly