Elmélkedés Kotlinnal

1. Bemutatkozás

A tükrözés az osztályok, mezők és módszerek futás közbeni ellenőrzésének, betöltésének és azokkal való interakció képességének a neve. Ezt akkor is megtehetjük, ha nem tudjuk, hogy mik azok a fordítás idején.

Ennek számos felhasználása van, attól függően, hogy mit fejlesztünk. Például az olyan keretrendszerek, mint a Spring, erősen használják.

Ennek támogatása beépül a JVM-be, és így implicit módon elérhető az összes JVM-alapú nyelv számára. Egyes JVM nyelvek azonban a már elérhetőeken felül extra támogatást nyújtanak.

2. Java reflexió

Az összes standard Java Reflection konstrukció elérhető és tökéletesen működik a Kotlin kóddal. Ide tartozik a java.lang.Osztály osztály, valamint minden a java.lang.reflect csomag.

Ha bármilyen okból a szabványos Java Reflection API-kat akarjuk használni, akkor azt ugyanúgy megtehetjük, mint a Java-ban. Például egy Kotlin osztály összes nyilvános módszerének felsorolásához tennénk:

MyClass :: class.java.methods

Ez a következő konstrukciókra bontható:

  • MyClass :: osztály megadja nekünk a Kotlin osztály reprezentációját Az osztályom osztály
  • .Jáva megadja nekünk a java.lang.Osztály egyenértékű
  • .mód felhívás a java.lang.Class.getMethods () accessor módszer

Ez pontosan ugyanúgy fog működni, függetlenül attól, hogy Java-ból vagy Kotlin-ből hívják-e meg, és hogy Java vagy Kotlin osztályon hívják-e. Ez magában foglalja a Kotlin-specifikus konstrukciókat, például az adatosztályokat.

adatosztály ExampleDataClass (val név: String, var engedélyezve: Boolean) ExampleDataClass :: class.java.methods.forEach (:: println)

Kotlin a visszaküldött típusokat konvertálja Kotlin reprezentációkká is.

A fentiekben a kotlin. Array amelyen felhívhatjuk az egyes().

3. Kotlin Reflection Enhancements

Bár használhatjuk a standard Java Reflection API-kat, nem ismeri az összes kiterjesztést, amelyet Kotlin a platformra hoz.

Ezenkívül esetenként kissé kényelmetlen lehet használni bizonyos helyzetekben. Kotlin hozza a saját reflexiós API-ját, amelyet felhasználhatunk ezeknek a problémáknak a megoldására.

A Kotlin Reflection API összes belépési pontja használja a Referenciákat. Korábban láttuk a ::osztály hogy utalást adjon az osztály definíciójára. Ezt arra is felhasználhatjuk, hogy referenciákat kapjunk a módszerekre és tulajdonságokra.

3.1. Kotlin osztály referenciák

A Kotlin Reflection API hozzáférést biztosít egy osztály referenciához. Ezt lehet felhasználni a Kotlin osztály teljes részleteinek felkutatására. Ez hozzáférést biztosít a Java osztály hivatkozáshoz - a java.lang.Osztály objektumot -, hanem a Kotlin összes részletét is.

A Kotlin API osztályrészletekhez a kotlin.reflect.KClass osztály. Ehhez a :: operátor bármely osztálynévből vagy példányból - például. Húr :: osztály.

Alternatív megoldásként a kiterjesztés módszerével érhető el java.lang.Class.kotlin ha Java Osztály példány elérhető számunkra:

val listClass: KClass = List :: class val name = "Baeldung" val stringClass: KClass = name :: class val someClass: Class val kotlinClass: KClass = someClass.kotlin

Miután megszereztük a KClass objektum, van néhány egyszerű dolog, amit elmondhat a kérdéses osztályról. Ezek némelyike ​​standard Java-koncepció, mások Kotlin-specifikus fogalmak.

Például könnyen megtudhatjuk, hogy egy osztály elvont vagy végleges, de azt is megtudhatjuk, hogy az osztály adatosztály vagy társosztály:

val stringClass = String :: class assertEquals ("kotlin.String", stringClass.qualifiedName) assertFalse (stringClass.isData) assertFalse (stringClass.isCompanion) assertFalse (stringClass.isAbstract) assertTrue (stringClass.isFinal) assertFalse (stringClASS.assFalse)

Arra is van módunk, hogy mozoghassunk az osztályhierarchiában. A Java-ban már elmozdulhatunk egy osztályról a szuperosztályára, az interfészekre és a külső osztályra, amelybe zárt - adott esetben.

Kotlin ehhez hozzáteszi a Companion Object megszerzésének képességét egy tetszőleges osztályhoz, és a Tárgy egy Object osztály példánya:

println (TestWithCompanion :: class.companionObject) println (TestWithCompanion :: class.companionObjectInstance) println (TestObject :: class.objectInstance)

Új osztálypéldányokat hozhatunk létre egy osztályreferenciából is, ugyanúgy, mint a Java-ban:

val listClass = ArrayList :: osztály val list = listClass.createInstance () assertTrue (a lista ArrayList)

Alternatív megoldásként hozzáférhetünk a kivitelezőkhöz, és szükség esetén egy kifejezettet használhatunk. Mindezek a következő szakaszban tárgyalt módszer-referenciák.

Nagyon hasonló módon hozzáférhetünk az osztály összes módszeréhez, tulajdonságához, kiterjesztéséhez és az osztály többi tagjához:

val bigDecimalClass = BigDecimal :: class println (bigDecimalClass.constructors) println (bigDecimalClass.functions) println (bigDecimalClass.memberProperties) println (bigDecimalClass.memberExtensionFunctions)

3.2. Kotlin-módszer hivatkozások

Amellett, hogy kapcsolatba léphet az Osztályokkal, kölcsönhatásba léphetünk a Módszerekkel és a Tulajdonságokkal is.

Ide tartoznak az osztály tulajdonságai - a val vagy var, szabványos osztályú módszerek és legfelső szintű függvények. Az előzőekhez hasonlóan ez ugyanolyan jól működik a standard Java-ban írt kódokon, mint a Kotlinban írt kódoknál.

Pontosan ugyanúgy, mint az osztályoknál, a. használatával hivatkozást szerezhetünk egy módszerre vagy tulajdonságra:: operátor.

Ez pontosan ugyanúgy néz ki, mint a Java 8-ban a metódus referencia megszerzéséhez, és pontosan ugyanúgy használhatjuk. Ugyanakkor Kotlinban ez a módszerre való hivatkozás felhasználható a célról reflexiós információk megszerzésére is.

Miután megszereztük a módszer referenciáját, úgy hívhatjuk, mintha valóban ez lenne a kérdéses módszer. Ez hívható hivatkozásként ismert:

val str = "Hello" val lengthMethod = str :: length assertEquals (5, lengthMethod ())

Magáról a módszerről is további részleteket kaphatunk, ugyanúgy, mint az órákon. Ez magában foglalja mind a standard Java-részleteket, mind a Kotlin-specifikus részleteket, például, ha a módszer egy operátor vagy ha mégis Sorban:

val byteInputStream = Karakterlánc :: byteInputStream assertEquals ("byteInputStream", byteInputStream.name) assertFalse (byteInputStream.isSuspend) assertFalse (byteInputStream.isExternal) assertTrue (byteInputStream.isInis) AssertFalse

Ezen felül ezen a referencián keresztül kaphatunk további információkat a módszer be- és kimeneteiről.

Ez magában foglalja a visszatérési típus és a paraméterek részleteit, beleértve a Kotlin-specifikus részleteket - például a semmisséget és az opcionális tulajdonságokat.

val str = "Hello" val method = str :: byteInputStream assertEquals (ByteArrayInputStream :: class.starProjectedType, method.returnType) assertFalse (method.returnType.isMarkedNullable) assertEquals (1, method.parameters.size) assertTrue (metódus.parameters.size) assertTrue (módszer. 0] .isOptional) assertFalse (method.parameters [0] .isVararg) assertEquals (Charset :: class.starProjectedType, method.parameters [0] .type)

3.3. Kotlin Property References

Ez pontosan ugyanúgy működik a Tulajdonságok esetében isbár nyilvánvalóan a megszerezhető részletek különbözőek. A tulajdonságok ehelyett tájékoztathatnak bennünket, ha konstansok, későn inicializáltak vagy módosíthatók:

lateinit var mutableProperty: String val mProperty = this :: mutableProperty assertEquals ("mutableProperty", mProperty.name) assertTrue (mProperty.isLateinit) assertFalse (mProperty.isConst) assertTrue (mProperty is KMutableProperty)

Vegye figyelembe, hogy a Tulajdonságok fogalma minden nem Kotlin kódban is működik. Ezeket olyan mezők azonosítják, amelyek betartják a JavaBeans konvencióit a getter és setter módszerekkel kapcsolatban.

Ez magában foglalja a Java szabványos könyvtár osztályait is. Például a Dobható osztály rendelkezik tulajdonsággal Dobható.üzenet annak a ténynek az alapján, hogy létezik módszer getMessage () meghatározza benne.

A tényleges Tulajdonhoz hozzáférhetünk a kitett módszer hivatkozásokon keresztül - a getter és szetter mód. A szetter csak akkor érhető el, ha a KMutableProperty - azaz az ingatlant úgy nyilvánították var, míg a getter mindig elérhető.

Ezek könnyebben használható módon vannak kitéve a kap() és készlet() mód. A getter és szetter az értékek tényleges módszer referenciák, lehetővé téve számunkra, hogy pontosan ugyanúgy dolgozzunk velük, mint bármely más módszer referencia:

val prop = this :: mutableProperty assertEquals (String :: class.starProjectedType, prop.getter.returnType) prop.set ("Hello") assertEquals ("Hello", prop.get ()) prop.setter ("Világ") assertEquals ("Világ", prop.getter ())

4. Összefoglalás

Ez a cikk áttekintést nyújt azokról a dolgokról, amelyeket a reflexióval el lehet érni Kotlinban, beleértve azt is, hogy miként hat egymással a szabványos Java nyelvbe beépített reflexiós képességekkel, és miben különbözik azoktól.

Az összes példa elérhető a GitHub oldalon.


$config[zx-auto] not found$config[zx-overlay] not found