Razmišljanje s Kotlinom

1. Uvod

Reflection je naziv za sposobnost pregledavanja, učitavanja i interakcije s klasama, poljima i metodama tijekom izvođenja. To možemo učiniti čak i kad ne znamo koje su one u vrijeme sastavljanja.

Ovo ima velik broj namjena, ovisno o tome što razvijamo. Na primjer, okviri poput Proljeća to jako koriste.

Podrška za to ugrađena je u JVM i stoga je implicitno dostupna za sve jezike temeljene na JVM-u. Međutim, neki JVM jezici imaju dodatnu podršku povrh onoga što je već dostupno.

2. Java Reflection

Dostupne su sve standardne konstrukcije Java Reflection i savršeno dobro rade s našim Kotlin kodom. To uključuje java.lang.Clasa klase kao i sve u java.lang.reflect paket.

Ako iz bilo kojeg razloga želimo koristiti standardne API-je Java Reflection, to možemo učiniti na potpuno isti način kao u Java-i. Na primjer, da bismo dobili popis svih javnih metoda u razredu Kotlin, učinili bismo:

MyClass :: class.java.methods

To se raščlanjuje na sljedeće konstrukcije:

  • MyClass :: klasa daje nam predstavljanje klase Kotlin za Moj razred razred
  • .Java daje nam java.lang.Clasa ekvivalent
  • .metode je poziv na java.lang.Class.getMethods () metoda pristupa

Ovo će raditi potpuno isto bez obzira poziva li se s Jave ili Kotlina i poziva li se na Java ili Kotlin klasi. To uključuje specifične konstrukcije za Kotlin, poput klasa podataka.

klasa podataka ExampleDataClass (ime vala: String, omogućeno var: Boolean) ExampleDataClass :: class.java.methods.forEach (:: println)

Kotlin također pretvara vraćene tipove u Kotlinove reprezentacije.

U gore navedenom dobivamo a kotlin.Array na koji se možemo pozvati za svakoga().

3. Poboljšanja refleksije Kotlina

Iako možemo koristiti standardne API-je Java Reflection, nije svjestan svih proširenja koja Kotlin donosi na platformu.

Uz to, ponekad može biti pomalo neugodno koristiti u nekim situacijama. Kotlin donosi vlastiti API za razmišljanje koji možemo koristiti za rješavanje ovih problema.

Sve ulazne točke u Kotlin Reflection API koriste reference. Ranije smo vidjeli upotrebu :: razred dati referencu na definiciju klase. To ćemo također moći koristiti za dobivanje referenci na metode i svojstva.

3.1. Reference klase Kotlin

Kotlin Reflection API omogućuje pristup referenci klase. To se zatim može koristiti za introspekciju svih detalja klase Kotlin. To daje pristup referenci Java Class - java.lang.Clasa objekt - ali i na sve specifičnosti Kotlina.

Kotlin API za detalje klase usredotočen je na kotlin.reflect.KClass razred. Ovome se može pristupiti pomoću :: operator iz bilo kojeg naziva klase ili instance - npr. String :: klasa.

Inače, može mu se pristupiti metodom produženja java.lang.Class.kotlin ako Java Razred instanca nam je dostupna:

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

Nakon što smo dobili a KClass Objekt, ima nekoliko jednostavnih stvari koje nam može reći o predmetnoj klasi. Neki od njih su standardni Java koncepti, a drugi su Kotlin specifični koncepti.

Na primjer, lako možemo saznati je li klasa apstraktna ili konačna, ali također možemo saznati je li klasa podatkovna ili prateća klasa:

val stringClass = Niz :: klasa assertEquals ("kotlin.String", stringClass.qualifiedName) assertFalse (stringClass.isData) assertFalse (stringClass.isCompanion) assertFalse (stringClass.isAbstract) assertTrue (stringClass.isfisal)

Imamo i načina kretanja po hijerarhiji razreda. U Javi već možemo prijeći iz klase u njezinu superklasu, sučelja i vanjsku klasu u koju je zatvorena - ako je prikladno.

Kotlin ovome dodaje mogućnost dobivanja pratećeg objekta za proizvoljnu klasu i Objekt primjer za klasu Object:

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

Možemo stvoriti nove primjerke klase i iz reference klase, na približno isti način kao na Javi:

val listClass = ArrayList :: klasa val list = listClass.createInstance () assertTrue (popis je ArrayList)

Alternativno, možemo pristupiti konstruktorima i koristiti eksplicitni ako je potrebno. Sve su to reference na metode kako je raspravljeno u sljedećem odjeljku.

Na vrlo sličan način možemo dobiti pristup svim metodama, svojstvima, proširenjima i ostalim članovima klase:

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

3.2. Reference metode Kotlina

Osim što mogu komunicirati s nastavom, također možemo komunicirati s metodama i svojstvima.

To uključuje svojstva klase - definirana s val ili var, standardne metode klase i funkcije najviše razine. Kao i prije, ovo jednako dobro djeluje na kodu napisanom na standardnoj Javi kao i na kodu napisanom u Kotlinu.

Na potpuno isti način kao i kod predavanja, možemo dobiti referencu na metodu ili svojstvo pomoću:: operater.

Ovo izgleda potpuno isto kao u Javi 8 za dobivanje reference metode i možemo je koristiti na potpuno isti način. Međutim, u Kotlinu se ova referenca metode također može koristiti za dobivanje informacija o odrazu cilja.

Nakon što smo dobili referencu za metodu, možemo je nazvati kao da je doista riječ o metodi. Ovo je poznato kao pozivna referenca:

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

Također možemo dobiti više detalja o samoj metodi, na isti način kao i za nastavu. To uključuje i standardne Java detalje, kao i specifične detalje Kotlina, na primjer, je li metoda operater ili ako je u redu:

val byteInputStream = String :: byteInputStream assertEquals ("byteInputStream", byteInputStream.name) assertFalse (byteInputStream.isSuspend) assertFalse (byteInputStream.isExternal) assertTrue (byteInputStreamis).

Uz ovo, putem ove reference možemo dobiti više informacija o ulazima i izlazima metode.

To uključuje detalje o vrsti povrata i parametrima, uključujući Kotlin specifične detalje - poput nulibilnosti i neobaveznosti.

val str = "Hello" val metoda = str :: byteInputStream assertEquals (ByteArrayInputStream :: class.starProjectedType, method.returnType) assertFalse (method.returnType.isMarkedNullable) assertEquals (1, method.parameters.size) assertTrue (method.parameters.size) assertTrue (method.parameters.size) assertTrue (method.parameters.size) assertTrue (method.parameters.size) assertTrue (method.parameters.size) 0] .isO optional) assertFalse (method.parameters [0] .isVararg) assertEquals (Charset :: class.starProjectedType, method.parameters [0] .type)

3.3. Kotlin reference nekretnine

To potpuno isto vrijedi i za Svojstva, iako su očito detalji koji se mogu dobiti različiti. Svojstva nas umjesto toga mogu obavijestiti jesu li konstante, kasno inicijalizirane ili promjenjive:

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

Imajte na umu da koncept svojstava također funkcionira u bilo kojem kodu koji nije Kotlin. Oni su identificirani poljima koja slijede JavaBeans konvencije u vezi s metodama dobivanja i postavljanja.

To uključuje nastavu u standardnoj knjižnici Java. Na primjer, Bacljivo razred ima Svojstvo Dohvatljivo.poruka na osnovu činjenice da postoji metoda getMessage () definirana u njemu.

Stvarnom svojstvu možemo pristupiti putem izloženih referenci metoda - the getter i seter metode. The seter dostupan je samo ako radimo s a KMutableProperty - tj. imovina je proglašena kao var, dok je getter je uvijek dostupan.

Oni su izloženi na lakši način za korištenje putem dobiti() i postavi () metode. The getter i seter vrijednosti su stvarne reference metode, što nam omogućuje rad s njima potpuno isti kao i bilo koja druga referenca metode:

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

4. Sažetak

Ovaj članak daje pregled nekih stvari koje se mogu postići refleksijom u Kotlinu, uključujući i način interakcije i razliku od mogućnosti refleksije ugrađene u standardni jezik Java.

Svi primjeri dostupni su na GitHubu.


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