Sobes.tech
Middle

Co je to reflexe a jak je implementováno v Kotlinu?

sobes.tech AI

Odpověď od AI

Reflexe v Kotlinu je možností prozkoumávat vlastnosti objektů, tříd a jejich členů během běhu programu. Umožňuje získat informace o typu objektu, jeho metodách, polích, konstruktorech a anotacích, stejně jako dynamicky volat metody a měnit hodnoty polí.

V Kotlinu je reflexe implementována pomocí API v balíčku kotlin.reflect. Pro práci s reflexí je nutné přidat závislost kotlin-reflect. Toto API poskytuje třídy reprezentující různé prvky jazyka:

  • KClass: reprezentuje třídu. Umožňuje získat název třídy, seznam konstruktorů, členů (metod a vlastností), nadtříd a další.
  • KCallable: obecné rozhraní pro funkce a vlastnosti, které lze volat.
  • KFunction: reprezentuje funkci. Umožňuje získat parametry, typ návratové hodnoty a volat funkci.
  • KProperty: reprezentuje vlastnost (proměnnou člena). Umožňuje získat typ vlastnosti, její viditelnost, anotace a získat nebo nastavit hodnotu.

Pro získání reflexivních objektů se používají operátory :: pro třídy, funkce a vlastnosti, nebo metody typu .java.kotlin pro získání KClass z Java Class.

Příklady použití:

// Získání KClass pomocí operátoru ::class
val personClass: KClass<Person> = Person::class

// Získání KClass z Java Class
val personJavaClass: Class<Person> = Person::class.java
val personKotlinClass: KClass<Person> = personJavaClass.kotlin

// Získání seznamu konstruktorů třídy
val constructors = personClass.constructors

// Získání seznamu členů třídy (vlastností a funkcí)
val members = personClass.members

// Získání KFunction pro metodu
val sayHelloFunction: KFunction<*> = personClass.members.find { it.name == "sayHello" } as KFunction<*>

// Volání metody přes reflexi
val personInstance = Person("Alice")
sayHelloFunction.call(personInstance)

// Získání KProperty pro vlastnost
val nameProperty: KProperty1<Person, String> = personClass.members.find { it.name == "name" } as KProperty1<Person, String>

// Získání hodnoty vlastnosti přes reflexi
val nameValue = nameProperty.get(personInstance)

// Nastavení hodnoty vlastnosti přes reflexi (pro měnitelné vlastnosti)
// val mutableNameProperty = personClass.members.find { it.name == "mutableName" } as KMutableProperty1<Person, String>
// mutableNameProperty.set(personInstance, "Bob")

Reflexe je užitečná pro:

  • Metaprogramování (ORM frameworky, serializace/deserializace).
  • Vytváření dynamických proxy a aspektů.
  • Testování (přístup k soukromým členům).
  • introspekci během běhu.

Je důležité pamatovat, že použití reflexe může snižovat výkon a ztěžovat kód, stejně jako může být méně bezpečné kvůli obcházení modifikátorů přístupu. Je třeba ji používat uvědoměle a tam, kde jiné přístupy nejsou efektivní nebo možné.