Explain Codes LogoExplain Codes Logo

Kotlin: Equivalent of getClass() for KClass

kotlin
reflection
generics
logging
Nikita BarsukovbyNikita Barsukov·Feb 28, 2025
TLDR

Fetching a Kotlin class's KClass is a walk in the park by using ::class:

val kClass = MyClass()::class // suspect KClass captured!

To flip this KClass to its Java Class, just tag on .java:

val javaClass = MyClass()::class.java // the Java imposter unmasks itself!

Briefly, ::class summons the Kotlin class whereas .java morphs it into its Java's Class doppelgänger.

To get hold of the simple name of the KClass (for logging perhaps?), take a peek at:

val className = MyClass::class.java.simpleName // a name only a mother could love

Kotlin 1.0 vs. 1.1+: A Tale of Two Kotlins

Over time, Kotlin has developed fractional memory loss. So, let's jog its memory real quick.

Kotlin 1.0: The era of '.kotlin'

Once upon a time, to obtain a KClass from a Java Class instance in Kotlin 1.0, one had to romance with the extension property .kotlin, as such:

val kClass = MyClass().javaClass.kotlin // grab Java's Class, then go 'kotlin' on it

This kotlin act, however, is now relagated to the archive in future versions of Kotlin.

Kotlin 1.1+: Enter the '::class' notation

From Kotlin 1.1 onwards, the ::class syntax chair danced its way onto the scene, simplifying the hustle to obtain a KClass instance:

val kClass = MyClass::class // Look, ma! No javaClass!

Kotlin 1.5.21+: Gazing into the crystal ball

Kotlin's reflex mirrors keep getting polished. Did you know, Kotlin 1.5.21 has a more effective way of fetching the Java class of our KClass? Also, shh… but (YourClassName as Any).javaClass is the secret handshake in the Kotlin town to gain the Java class for usage across all departments due to the retirement ceremony of KClass<>.javaClass.

Practical use-cases of '::class' notation

It's show-time! Let's explore the power of ::class in several real-world programming scenarios.

Generics and type-thirsty parameters

When generics wreak havoc with 'Not enough information to infer type variable T' error, you wave your ::class wand:

inline fun <reified T: Any> printGenericClassInfo() { println(T::class.java.simpleName) // Oh look! generics play nice here } printGenericClassInfo<MyClass>() // Let's bring 'MyClass' into play

Logging canvas: TAG declaration

For every log in Android forest, there's a TAG, derived by:

companion object { val TAG = MyClass::class.java.simpleName // Ready to be logged and tamed }

We have a clear winner!

Reflection's pawns: instances

To reflect on an instance at runtime, ::class gets invigorated:

val myObject = MyClass() val kClass = myObject::class // KClass flexes its runtime muscle