KClass is Kotlin’s runtime representation of a class or object. Obtain one with ClassName::class when the class is known statically, or obj::class from an instance. It is the entry point for inspecting declarations dynamically: properties, functions, constructors, nested classes, and superclass members. section 12.2.1 section 12.3
import kotlin.reflect.full.*
class Person(val name: String, val age: Int)
fun main() {
val person = Person("Alice", 29)
val kClass = person::class #1
println(kClass.simpleName)
// Person
kClass.memberProperties.forEach { println(it.name) }
// age
// name
}
Inspect an object’s runtime class, print its name, and enumerate its member properties. section 12.2.1
A KClass value supports several practical reflection tasks:
- Read simpleName or qualifiedName. Both are nullable because an anonymous object still has a class but no class name. section 12.2.1
- Enumerate members through members, whose elements are KCallable instances, or use extensions such as memberProperties to include nonextension properties from superclasses. section 12.2.1
- Access constructors and nestedClasses as runtime class declarations. section 12.2.1
- Pass a class reference to an annotation, such as CompanyImpl::class, while retaining the referenced class in the KClass type parameter. section 12.1.6
annotation class DeserializeInterface(val targetClass: KClass<out Any>)
Use KClass<out Any> when an annotation parameter should accept references to any class extending Any, including CompanyImpl::class. section 12.1.6
KClass works with the wider reflection hierarchy rather than replacing callable references. Class members are KCallable values; functions and properties can be invoked or read through their specialized KFunction and KProperty APIs. Reflective calls validate arguments at runtime, so a wrong argument count causes an exception rather than a compile-time error. section 12.2.1 section 12.3
Annotation-driven serialization
A serializer can start from obj::class, collect memberProperties, and filter properties marked with JsonExclude. It can then inspect JsonName to choose an output name. For a CustomSerializer annotation, its KClass reference supplies either an object instance or a newly created serializer instance. section 12.2.3 section 12.2.3
Listing 12.2 Serializing an object with property filtering
private fun StringBuilder.serializeObject(obj: Any) {
(obj::class as KClass<Any>)
.memberProperties
.filter { it.findAnnotation<JsonExclude>() == null }
.joinToStringBuilder(this, prefix = "{", postfix = "}") {
serializeProperty(it, obj)
}
}
The serializer obtains a KClass from an object, filters reflected properties by annotation, and serializes each remaining property. section 12.2.3
Use KClass when behavior depends on runtime declarations or when an annotation must name a class. Keep the generic type precise where possible: CompanyImpl::class is KClass<CompanyImpl>, and an out-projected parameter can accept that more specific reference. From there, reflection can connect class metadata to property access, annotations, and configurable serialization behavior. section 12.1.6 section 12.2.3
