In Kotlin, what does the built-in standard library give you for reflection out of the box, and when do you need to add the kotlin-reflect dependency?
answer
- ::class works; full reflection needs the JAR
- org.jetbrains.kotlin:kotlin-reflect
- KotlinReflectionNotSupportedError when missing
- kotlin.reflect.full package = the rich API
- Spring/Jackson pull it in transitively
basics
~10 sBasic things like ::class work without extra setup. Richer reflection (reading properties, functions, parameters, supertypes) needs the separate kotlin-reflect library added to your build.
solid answer
~30 sThe kotlin-stdlib ships a tiny built-in reflection surface: the ::class operator gives you a KClass, but on stdlib alone you can mostly only read simpleName/qualifiedName and do basic identity/cast checks. Anything richer — listing members (memberProperties, declaredFunctions), reading constructors, supertypes, visibility, calling members, mapping a KClass to its Java counterpart fully, createInstance() — lives in the org.jetbrains.kotlin:kotlin-reflect artifact. You add it explicitly (e.g. implementation("org.jetbrains.kotlin:kotlin-reflect")). At runtime, calling a full-reflection API without kotlin-reflect on the classpath throws KotlinReflectionNotSupportedError. Many frameworks (Spring, Jackson Kotlin module) pull it in transitively, which is why people forget it is a separate dependency.
code
kotlin · 12 linesimport kotlin.reflect.full.memberProperties
data class User(val id: Long, val name: String)
fun main() {
// Works without kotlin-reflect:
println(User::class.simpleName) // "User"
// Requires kotlin-reflect on the classpath, else
// KotlinReflectionNotSupportedError at runtime:
User::class.memberProperties.forEach { println(it.name) }
}go deeper
Knows ::class works out of the box and that a separate library is needed for 'more'.
Names org.jetbrains.kotlin:kotlin-reflect and the kotlin.reflect.full APIs that require it.
Explains the runtime KotlinReflectionNotSupportedError and how frameworks pull the artifact in transitively.
Frames the two-JAR split as a deliberate cost-isolation design and reasons about when to keep reflection out entirely.
## Two reflection surfaces in Kotlin Kotlin splits reflection into two layers shipped in two different JARs: - **kotlin-stdlib** (always present): a minimal built-in reflection surface. The `::class` operator and `KClass` type live here, but only a thin slice of `KClass` actually works without the full library. - **kotlin-reflect** (`org.jetbrains.kotlin:kotlin-reflect`): the *full* implementation that backs the rich `kotlin.reflect.full` and `kotlin.reflect.jvm` APIs. ## What `::class` gives you without kotlin-reflect The `::class` operator (e.g. `String::class` or `value::class`) returns a `KClass<T>`. On stdlib alone you can reliably use: - `simpleName`, `qualifiedName` - `isInstance(obj)` - `.java` to bridge to a `java.lang.Class` (for plain Java reflection) ```kotlin val k: KClass<String> = String::class // works on stdlib alone println(k.simpleName) // "String" println(k.java.name) // bridge to java.lang.Class ``` ## What requires kotlin-reflect The richer members live mostly in the `kotlin.reflect.full` package and on `KCallable`/`KProperty`: - `memberProperties`, `declaredMemberProperties`, `declaredFunctions` - `primaryConstructor`, `constructors`, `createInstance()` - `supertypes`, `isData`, `visibility`, `isSealed` - Calling a `KFunction`/`KProperty` reflectively via `.call(...)` / `.get(...)` If you call one of these and kotlin-reflect is **not** on the classpath, the runtime throws `kotlin.reflect.jvm.internal.KotlinReflectionNotSupportedError`. ## How to add it ```kotlin dependencies { implementation("org.jetbrains.kotlin:kotlin-reflect") } ``` Version is usually managed by the Kotlin Gradle plugin's BOM/alignment, so you should match it to your Kotlin compiler version. Note many libraries (Spring, Jackson's `jackson-module-kotlin`) already pull it in transitively. ## Why the split exists Full reflection metadata and machinery is large and has startup/size cost. Keeping it out of stdlib means the common case (no reflection, or only `::class` identity checks) stays lightweight.
- What exact error do you get if you call memberProperties without kotlin-reflect?A KotlinReflectionNotSupportedError is thrown at runtime — it is an Error, not a checked exception, so it usually surfaces as a crash.
- Why might it 'just work' in a Spring app even though you never added kotlin-reflect?Spring (and Jackson's Kotlin module) declare kotlin-reflect as a transitive dependency, so it ends up on the classpath without you adding it explicitly.
stdlib reflection is a name tag (who are you); kotlin-reflect is the full medical chart (every detail) — you only carry the chart when you need it.
saying these in an interview costs you the question
- Thinking all of KClass works from stdlib alone
- Claiming kotlin-reflect is bundled in kotlin-stdlib
- Not knowing the missing-dependency failure is a runtime error
- Confusing kotlin-reflect with Java's java.lang.reflect