Reflection

Reflection is the ability of a program to examine its own structure and behavior at runtime. Reflection is a powerful tool, but it should be used with care. It is easy to write programs that use reflection to do things that would be much better done in a more straightforward way. Reflection is also a source of considerable complexity, and it is easy to write programs that are hard to understand because they use reflection in complex ways.

  • Object oriented API for metadata;
  • Set of features that allow to examine the code structure at runtime.
KotlinJava
kotlin.reflectjava.lang.reflect
KClassClass
KCallableMember
KFunctionMethod
KPropertyField
  • KClass.java -> Class;
  • Class.kotlin -> KClass.

Kotlin Reflection


KClass

Represents a class and provides introspection capabilities.

val c: KClass<MyClass> = MyClass::class
// or
val instance = MyClass()
val c: KClass<MyClass> = instance::class

Relevant properties and methods:

  • constructors;
  • isAbstract;
  • isCompanion;
  • isData;
  • isSealed;
  • members;
  • objectInstance;
  • qualifiedName;
  • simpleName;
  • visibility: returns KVisibility, which can be PUBLIC, PROTECTED, INTERNAL ou PRIVATE;
  • annotations;
  • memberProperties;
  • memberExtensionProperties;
  • declaredMemberProperties;
  • declaredMemberExtensionProperties;
  • memberFunctions;
  • memberExtensionFunctions;
  • declaredMemberFunctions;
  • declaredMemberExtensionFunctions;
  • declaredMembers;
  • java
  • primaryConstructor;
  • createInstance
  • createType: returns [KType](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-type/);
  • findAnnotation;
  • hasAnnotation;
  • isSubclassOf;
  • isSuperclassOf;
MethodsExtensionNon-ExtensionDeclared only in this classDeclared in this class and superclasses
memberPropertiesXX
memberExtensionPropertiesXX
declaredMemberPropertiesXX
declaredMemberExtensionFunctionsXX
staticXX
MethodsType
memberPropertiesKProperty1
declaredMemberPropertiesKProperty1
memberExtensionPropertiesKProperty2
declaredMemberExtensionFunctionsKProperty2

KCallable

Represents a callable entity, such as a function or a property.

Relevant properties and methods:

  • KCallable<out R>.call(args):R;
  • name;
  • parameters;
  • returnType: returns [KType](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-type/);
  • typeParameters;
  • visibility;
  • annotations;
  • callBy;
  • instanceParameter;
  • findParameterByName;
  • findAnnotation;
  • hasAnnotation;

KProperty

Represents a property, such as a named val or var declaration.

To access properties as first-class objects in Kotlin, use the :: operator:

var x = 1

::x.get()
::x.set(2)
::x.name

The expression ::x evaluates to a KProperty<Int> type property object.

Relevant properties and methods:

  • isConst;
  • isLateinit;
  • getter;

Is superclass of KMutableProperty, which has the setter property and the set(instance, value) method, equivalent to setter.call(instance, value).

KFunction

Represents a function with introspection capabilities.

You can use the function as a function type value, that is, pass it to another function. To do so, use the :: operator:

fun isOdd(x: Int) = x % 2 != 0 is referenced by ::isOdd -> here ::isOdd is a value of function type (Int) -> Boolean.

Relevant properties and methods:

  • isInline;
  • isOperator;
  • isSuspend;

KParameter

Represents a parameter passed to a function or a property getter/setter, including this and extension receiver parameters.

Relevant properties and methods:

  • isOptional;
  • isVararg;
  • kind;
  • name;
  • type;
  • findAnnotation;
  • hasAnnotation;

KType

Represents a type. Type is usually either a class with optional type arguments, or a type parameter of some declaration, plus nullability.

To get the KClass associated with a KType there are two ways:

  • KType.classifier as KClass<*>;
  • KType.jvmErasure;


Annotations

Annotations are metadata that you can add to your code to convey information to the compiler and other tools.

  • Allow us to add metadata to our code.
  • Are created by using the annotation keyword:
annotation class Fancy

We can annotate annotations with other annotations:

@Target(AnnotationTarget.CLASS)
annotation class Fancy

@Target: specifies the possible kinds of elements which can be annotated with the annotation (such as classes, functions, properties, and expressions); receives a list of AnnotationTarget values:

  • CLASS;
  • ANNOTATION_CLASS;
  • PROPERTY;
  • FIELD;
  • CONSTRUCTOR;
  • FUNCTION;
  • PROPERTY_GETTER;
  • PROPERTY_SETTER;
  • TYPE;
  • TYPE_PARAMETER;
  • LOCAL_VARIABLE;
  • VALUE_PARAMETER;
  • EXPRESSION;
  • FILE;
  • TYPEALIAS.

@Retention: specifies the retention policy of the annotation (whether the annotation is stored in the compiled class file, is available in the reflection information, or is ignored by the compiler); receives a AnnotationRetention value:

  • SOURCE: the annotation is not stored in the compiled class file, only in the source code;
  • RUNTIME: the annotation is stored in the compiled class file and is available in the reflection information;
  • BINARY: the annotation is stored in the compiled class file, but is not available in the reflection information.

@Repeatable: allows using the same annotation on a single element multiple times;

The allowed parameters in annotation constructors are:

  • Primitive types;
  • String;
  • KClass;
  • Enum;
  • Annotations;
  • Arrays.

In the Reflection API, the KAnnotatedElement type is the superclass of all annotated element types, such as KClass, KCallable, KParameter, etc.

This type has the annotations property, which returns a list of Annotation objects. Also contains the following methods:

  • hasAnnotation<T: Annotation>(): Boolean;
  • findAnnotation<T: Annotation>(): T?.

LAE - Languages and Managed Runtimes (Linguagens e Ambientes de Execução)

Last updated: November 17, 2022