How are class names generated?

To understand how to control generated class naming, we'll explore how these class names are generated by the Kotlin compiler by default. In this snippet, we've defined a new top-level function named sayHello():

// GreetingFunctions.kt
fun sayHello(name: String) = println("Hello $name!")

This function prints a simple greeting and can be used freely from the rest of our Kotlin code, like this:

// Main.kt
fun main() {
sayHello("Nate")
}

In this Kotlin case, calling the top-level function feels like a natural part of the language because the function is freely available, and is not associated with any class. However, from Java's perspective, that's not the case. To invoke the sayHello() function from Java, we must reference the function as a static method on a generated class:

// Main.java
public class Main {
public static void main(String[] args) {
GreetingFunctionsKt.sayHello("Nate");
}
}

To understand how this works, and ultimately how we can control this behavior, we can turn to the decompiled Kotlin bytecode for the top-level function:

public final class GreetingFunctionsKt {
public static final void sayHello(@NotNull String name) {
Intrinsics.checkParameterIsNotNull(name, "name");
String var1 = "Hello " + name + '!';
System.out.println(var1);
}
}

In this decompiled bytecode, we can see that the compiler has generated the GreetingFunctionsKt class for us with our top-level function as a static method on the class.

By default, the Kotlin compiler-generated class name is defined using the following format: <kotlin file name>Kt. In our example, sayHello() was declared within GreetingFunctions.kt, so the class name that's generated becomes GreetingFunctionsKt

Now that we understand that the generated class name is derived from the filename in which the top-level function was declared, we can take a look at how to customize this class name with the @JvmName annotation.