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é.