What is KType in Kotlin reflection, and what does it represent that a KClass cannot?
answer
- KType = type usage (List<String>?), KClass = declaration (List)
- Three parts: classifier, arguments, isMarkedNullable
- Generics survive in KType despite JVM erasure
- typeOf<T>() is the safe way to get one
basics
~20 sKType describes a full type used in code, like List<String>?. It knows the type arguments and whether the type can be null. A KClass only knows the bare class (List), not its arguments or nullability.
solid answer
~40 sKType is the reflection representation of a Kotlin type as written in source, e.g. List<String>?. It carries three things a KClass alone cannot: the classifier (the underlying KClass or type parameter via the classifier property), the type arguments (List<KTypeProjection> via arguments, capturing the String in List<String>), and nullability (isMarkedNullable, true for List<String>?). KClass only models the declaration of a class without generics or nullability, so List<String> and List<Int> share one KClass but are distinct KTypes. You obtain a KType most safely with typeOf<List<String>>() rather than building one by hand. KType is essential when you need the actual generic shape at runtime, for example in serialization libraries (kotlinx.serialization) that must distinguish List<String> from List<Int> despite JVM type erasure.
code
kotlin · 7 linesimport kotlin.reflect.typeOf
val a = typeOf<List<String>>()
val b = typeOf<List<Int>>()
println(a == b) // false — different arguments
println(a.classifier == b.classifier) // true — same KClass (List)
println(typeOf<String>() == typeOf<String?>()) // false — nullability differsgo deeper
Can state that KType represents a full type with generics and nullability, unlike KClass.
Names classifier, arguments, isMarkedNullable and explains why serialization needs KType.
Connects KType to JVM erasure and KTypeProjection/variance details.
Frames KType as the runtime carrier of source type information that bridges erased JVM generics for library design.
## What KType is `KType` (in package `kotlin.reflect`) is the reflection model of a *type usage* — exactly the type as written at a use site, such as `List<String>?`, `Map<String, Int>`, or `Array<out Number>`. Contrast this with `KClass`, which models a *class declaration* (`List`, `Map`) without any generic arguments or nullability. ## The three pieces of information KType carries - **classifier** (`KType.classifier: KClassifier?`): the thing being instantiated — either a `KClass` (for an ordinary class) or a `KTypeParameter` (for a generic type variable like `T`). - **arguments** (`KType.arguments: List<KTypeProjection>`): the generic type arguments. For `List<String>` this is one `KTypeProjection` wrapping the `KType` for `String`. A `KTypeProjection` also records *variance* (`in`/`out`/invariant) and supports star projections (`*`). - **isMarkedNullable** (`KType.isMarkedNullable: Boolean`): whether the type was written with a trailing `?`. `String?` is marked nullable; `String` is not. ```kotlin import kotlin.reflect.typeOf val t = typeOf<List<String>?>() println(t.classifier) // class kotlin.collections.List println(t.isMarkedNullable) // true println(t.arguments) // [String] println(t.arguments[0].type) // kotlin.String ``` ## Why KClass is not enough The JVM erases generics, so at runtime `List<String>` and `List<Int>` are both just `List`. Their `KClass` is identical. But their `KType` differs because `KType` preserves the source-level generic arguments. This is precisely why libraries like **kotlinx.serialization** accept a `KType` (or use `typeOf<T>()`) instead of a `KClass` — they need to know it is a `List<String>` to serialize each element correctly. ## Equality Two `KType` instances are equal only if classifier, arguments, and nullability all match. So `typeOf<List<String>>() != typeOf<List<Int>>()` and `typeOf<String>() != typeOf<String?>()`.
- Can two different KTypes share the same KClass?Yes. List<String> and List<Int> have the same classifier KClass (List) but are different KTypes because their arguments differ.
- How do you read the element type of a List<String> KType?Through type.arguments[0].type, which gives the KType for String (or null for a star projection).
KClass is the blank form (a 'List'); KType is the filled-in form ('List of String, may be empty/null').
saying these in an interview costs you the question
- Saying KType and KClass are the same thing
- Claiming generics are always lost at runtime in Kotlin
- Thinking KType ignores nullability
- Confusing classifier with the type arguments