skip to content

KClass vs Java Class (.java/.kotlin)

The .java and .kotlin properties convert between KClass and java.lang.Class, which you need whenever a Java framework wants a Class literal. It is a small thing you hit within a day of using Spring or Jackson from Kotlin.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

In Kotlin, how do you convert a KClass to a java.lang.Class and back again? Name the exact extension properties.

level: juniorimportance: must knowfreq 70%

answer

  1. .java goes KClass -> Class
  2. .kotlin goes Class -> KClass
  3. MyType::class.java == Java's MyType.class
  4. javaObjectType for boxed primitives
  5. ::class gives KClass, never Class directly

basics

~10 s

Kotlin has two class objects. Use the .java property to turn a Kotlin class into a Java Class, and the .kotlin property to turn a Java Class back into a Kotlin one.

solid answer

~30 s

Kotlin reflection exposes KClass<T>, while the JVM and Java libraries use java.lang.Class<T>. The kotlin-stdlib provides two extension properties to bridge them: KClass<T>.java returns the corresponding java.lang.Class<T>, and Class<T>.kotlin returns the corresponding KClass<T>. So `String::class` is a KClass<String>, `String::class.java` is Class<String> (equivalent to Java's String.class), and `someJavaClass.kotlin` converts back. You typically need `.java` when passing a type token to a Java/Spring/Jackson API that expects Class, e.g. `objectMapper.readValue(json, MyDto::class.java)`. The `.kotlin` direction appears when a framework hands you a raw Class and you want richer Kotlin reflection.

code

kotlin · 6 lines
kotlin
val kclass: KClass<String> = String::class
val javaClass: Class<String> = kclass.java        // KClass -> Class
val backToK: KClass<String> = javaClass.kotlin    // Class -> KClass

println(Int::class.java)            // int
println(Int::class.javaObjectType)  // class java.lang.Integer

go deeper

for a junior

Knows .java converts KClass to Class and .kotlin converts back; can pass MyType::class.java to a Java API.

for a middle

Explains why there are two handles and recalls MyType::class.java equals Java's MyType.class; aware of javaObjectType.

for a senior

Distinguishes primitive vs boxed via java/javaObjectType and notes stdlib-only cost for basic conversion.

for a principal

Frames the bridge in terms of interop boundaries and when richer KClass reflection justifies the kotlin-reflect dependency.

## Two class objects on the JVM Kotlin running on the JVM has **two** runtime representations of a type: - `java.lang.Class<T>` — the standard JVM/Java reflection handle. In Java you get it with `String.class` or `obj.getClass()`. - `kotlin.reflect.KClass<T>` — Kotlin's own reflection handle, which understands Kotlin-only concepts (nullability, `data` classes, companion objects, properties, visibility modifiers like `internal`, etc.). You obtain a `KClass` with the **class reference operator** `::class`: ```kotlin val k: KClass<String> = String::class // KClass<String> val kFromInstance = "hi"::class // KClass<out String> ``` ## Bridging with .java and .kotlin The stdlib defines two **extension properties** to convert between them: ```kotlin val c: Class<String> = String::class.java // KClass -> java.lang.Class val k: KClass<String> = c.kotlin // java.lang.Class -> KClass ``` - `KClass<T>.java` gives the `java.lang.Class<T>` — this is the Kotlin equivalent of Java's `MyType.class`. - `Class<T>.kotlin` gives back the `KClass<T>`. Note the convenient identity: `String::class.java` is the same as Java's `String.class`, so any Java API expecting a `Class` token takes `MyType::class.java`. ## Why two steps for a Java token There is **no** `MyType.class` syntax in Kotlin. The idiom is always `MyType::class.java`: first take the class reference (`::class` -> KClass), then convert (`.java` -> Class). ## javaObjectType vs java for primitives For types that map to JVM primitives, `KClass.java` can return the **primitive** Class, while `KClass.javaObjectType` returns the **boxed** wrapper: ```kotlin Int::class.java // int (primitive class) Int::class.javaObjectType // class java.lang.Integer ``` This matters when a generic Java API needs the wrapper type. ## Recap `.java` and `.kotlin` are zero-ceremony, lightweight conversions that just unwrap/wrap the underlying type handle; they do not require the heavyweight `kotlin-reflect` artifact (basic `::class` and `.java` work with stdlib alone).

  • What is the Kotlin equivalent of Java's String.class?
    String::class.java — take the KClass with ::class, then convert with the .java extension property.
  • Does using .java require the kotlin-reflect dependency?
    No. ::class and the .java property are provided by kotlin-stdlib; only deeper Kotlin reflection (members, supertypes, etc.) needs kotlin-reflect.

Two passports for the same person: .java and .kotlin just swap which one you show at the border.

saying these in an interview costs you the question

  • Thinking Kotlin has MyType.class syntax like Java
  • Confusing the direction of .java vs .kotlin
  • Saying KClass and Class are the same object
  • Believing .java needs the kotlin-reflect artifact

context

open as a page

Why do JVM frameworks like Jackson, Spring, or JPA require you to pass MyType::class.java instead of MyType::class?

level: middleimportance: must knowfreq 65%

basics

~10 s

Those frameworks are written in Java and only understand Java's Class type. Kotlin's KClass is a different type, so you convert it with .java before handing it over.

open as a page

What is the difference between Int::class.java and Int::class.javaObjectType, and when does it bite you?

level: seniorimportance: should knowfreq 35%

basics

~10 s

For number-like types, .java may give the primitive class (like int) while .javaObjectType gives the boxed wrapper (like Integer). Some Java APIs only accept the wrapper, so the wrong one fails.

open as a page

You're designing a generic serializer/registry API in Kotlin that interops with Java libraries. When would you accept/store a KClass<T> versus a java.lang.Class<T>, and how do you convert at the boundary?

level: seniorimportance: should knowfreq 25%

basics

~10 s

Use KClass in your Kotlin-facing API so callers write MyType::class and you can read Kotlin info; convert to .java at the exact point you call into Java libraries. Store whichever the consumers key on.

open as a page

Is `SomeClass::class.java.kotlin === SomeClass::class` guaranteed? What identity guarantees do the .java/.kotlin conversions give?

level: middleimportance: nice to knowfreq 20%

basics

~10 s

Round-tripping a class through .java and back to .kotlin gives you an equal KClass, and comparing with == works. The conversions are cheap lookups, not new copies of your data.

open as a page