Čo je to reflexia a ako je implementovaná v Kotlin?
sobes.tech AI
Odpoveď od AI
Reflexia v Kotlin je možnosť skúmať vlastnosti objektov, tried a ich členov počas behu programu. Umožňuje získavať informácie o type objektu, jeho metódach, poliach, konštruktoch a anotáciách, ako aj dynamicky volať metódy a meniť hodnoty polí.
V Kotlin je reflexia implementovaná pomocou API v balíku kotlin.reflect. Pre prácu s reflexiou je potrebné pridať závislosť kotlin-reflect. Toto API poskytuje triedy reprezentujúce rôzne prvky jazyka:
KClass: reprezentuje triedu. Umožňuje získať názov triedy, zoznam konštruktorov, členov (metód a vlastností), nadtried a pod.KCallable: všeobecné rozhranie pre funkcie a vlastnosti, ktoré je možné volať.KFunction: reprezentuje funkciu. Umožňuje získať parametre, typ návratovej hodnoty a volať funkciu.KProperty: reprezentuje vlastnosť (členskú premennú). Umožňuje získať typ vlastnosti, jej viditeľnosť, anotácie a získať alebo nastaviť hodnotu.
Na získanie reflexívnych objektov sa používajú operátory :: pre triedy, funkcie a vlastnosti, alebo metódy typu .java.kotlin na získanie KClass z Java Class.
Príklady použitia:
// Získanie KClass pomocou operátora ::class
val personClass: KClass<Person> = Person::class
// Získanie KClass z Java Class
val personJavaClass: Class<Person> = Person::class.java
val personKotlinClass: KClass<Person> = personJavaClass.kotlin
// Získanie zoznamu konštruktorov triedy
val constructors = personClass.constructors
// Získanie zoznamu členov triedy (vlastností a funkcií)
val members = personClass.members
// Získanie KFunction pre metódu
val sayHelloFunction: KFunction<*> = personClass.members.find { it.name == "sayHello" } as KFunction<*>
// Volanie metódy cez reflexiu
val personInstance = Person("Alice")
sayHelloFunction.call(personInstance)
// Získanie KProperty pre vlastnosť
val nameProperty: KProperty1<Person, String> = personClass.members.find { it.name == "name" } as KProperty1<Person, String>
// Získanie hodnoty vlastnosti cez reflexiu
val nameValue = nameProperty.get(personInstance)
// Nastavenie hodnoty vlastnosti cez reflexiu (pre meniteľné vlastnosti)
// val mutableNameProperty = personClass.members.find { it.name == "mutableName" } as KMutableProperty1<Person, String>
// mutableNameProperty.set(personInstance, "Bob")
Reflexia je užitočná pre:
- Metaprogramovanie (ORM rámce, serializácia/deserializácia).
- Vytváranie dynamických proxy a aspektov.
- Testovanie (prístup k súkromným členom).
- introspekciu počas behu.
Je dôležité pamätať, že použitie reflexie môže znižovať výkon a sťažovať kód, ako aj stať sa menej bezpečným kvôli obchádzaniu modifikátorov prístupu. Je potrebné ju používať vedome a tam, kde iné prístupy nie sú efektívne alebo možné.