Kotlin Academy · Lektion

Praktisk reflection

Læs annotations dynamisk

Lektion 4 af 413 trin

Praktisk reflection er en gratis Kotlin Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Kotlin Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Kotlin Academy-kurset indeholder 4 lektioner i alt.

Annotationer møder refleksion

En annotation med RUNTIME-bevaring kan findes under kørsel via refleksion. Denne kombination bruges til serialisering, validering og afhængighedsinjektion.

I denne lektion læser vi vores egne annotationer dynamisk.

Læsning af en klasseannotation

Alle KClass-objekter stiller en liste med annotations til rådighed. Vi kan gennemgå den for at finde en bestemt annotation efter type.

@Retention(AnnotationRetention.RUNTIME)
annotation class Entity(val table: String)

@Entity("users")
class User

fun main() {
    val ann = User::class.annotations
        .filterIsInstance<Entity>()
        .first()
    println(ann.table)
}

findAnnotation-hjælper

Udvidelsen findAnnotation er mere elegant end manuel filtrering. Den returnerer annotationen eller null.

import kotlin.reflect.full.findAnnotation

@Retention(AnnotationRetention.RUNTIME)
annotation class Entity(val table: String)

@Entity("orders")
class Order

fun main() {
    val ann = Order::class.findAnnotation<Entity>()
    println(ann?.table)
}

Annotationer på egenskaber

Egenskaber har deres egne annotationer. Gennemløb memberProperties, og undersøg hver egenskabs annotations.

import kotlin.reflect.full.memberProperties
import kotlin.reflect.full.findAnnotation

@Retention(AnnotationRetention.RUNTIME)
annotation class Column(val name: String)

class Product(@Column("product_id") val id: Int, val title: String)

fun main() {
    Product::class.memberProperties.forEach { prop ->
        val col = prop.findAnnotation<Column>()
        if (col != null) println(prop.name + " -> " + col.name)
    }
}

Oprettelse af en mini-serialiserer

Kombinér læsning af egenskaber med annotationer for at generere et resultat. Her mapper vi hver egenskab til en streng på formen nøgle=værdi og bruger kolonnenavnet, hvis det findes.

import kotlin.reflect.full.memberProperties
import kotlin.reflect.full.findAnnotation

@Retention(AnnotationRetention.RUNTIME)
annotation class Column(val name: String)

class Item(@Column("item_id") val id: Int, val name: String)

fun main() {
    val item = Item(7, "Book")
    val parts = Item::class.memberProperties.map { p ->
        val key = p.findAnnotation<Column>()?.name ?: p.name
        key + "=" + p.getter.call(item)
    }
    println(parts.joinToString(", "))
}

Spring over med en markør

En markørannotation kan markere egenskaber, der skal ignoreres. Vi kontrollerer, om den findes, med hasAnnotation.

import kotlin.reflect.full.memberProperties
import kotlin.reflect.full.hasAnnotation

@Retention(AnnotationRetention.RUNTIME)
annotation class Transient2

class Account(val id: Int, @Transient2 val secret: String)

fun main() {
    Account::class.memberProperties
        .filterNot { it.hasAnnotation<Transient2>() }
        .forEach { println(it.name) }
}

Læsning af annotationers argumenter

Når du har instansen af annotationen, er dens parametre almindelige egenskaber. Læs dem som ethvert andet felt.

import kotlin.reflect.full.findAnnotation

@Retention(AnnotationRetention.RUNTIME)
annotation class Validated(val min: Int, val max: Int)

@Validated(min = 1, max = 100)
class Quantity

fun main() {
    val v = Quantity::class.findAnnotation<Validated>()!!
    println("range " + v.min + ".." + v.max)
}

Annotationer på funktioner

Funktioner kan også annoteres og undersøges. Rammeværk bruger dette til at finde håndteringsfunktioner, f.eks. når testrunnere finder testmetoder.

import kotlin.reflect.full.memberFunctions
import kotlin.reflect.full.findAnnotation

@Retention(AnnotationRetention.RUNTIME)
annotation class Route(val path: String)

class Api {
    @Route("/home")
    fun home() = "home page"
}

fun main() {
    Api::class.memberFunctions.forEach { f ->
        f.findAnnotation<Route>()?.let { println(f.name + " @ " + it.path) }
    }
}

Styring af adfærd

Læs ruteannotationen, og videresend faktisk et kald. Det er grundideen bag rutehåndteringsrammeværk.

import kotlin.reflect.full.memberFunctions
import kotlin.reflect.full.findAnnotation

@Retention(AnnotationRetention.RUNTIME)
annotation class Route(val path: String)

class Api {
    @Route("/ping")
    fun ping() = "pong"
}

fun main() {
    val api = Api()
    val target = "/ping"
    Api::class.memberFunctions.forEach { f ->
        if (f.findAnnotation<Route>()?.path == target) {
            println(f.call(api))
        }
    }
}

Praktiske anvendelser

Refleksionsbaseret brug af annotationer danner grundlag for mange biblioteker:

  • JSON-serialisering, der mapper felter til nøgler
  • Validering, der håndhæver begrænsninger
  • Rutehåndtering, der matcher stier med håndteringsfunktioner
  • Afhængighedsinjektion, der forbinder komponenter

Hold det målrettet

Refleksion er bedst begrænset til initialisering og rammeværkskode, der kun kører én gang eller sjældent. Gem resultaterne i en cache, når du kan. Til ydeevnekritiske stier pr. forespørgsel bør du foretrække behandling ved kompilering.

Hurtigt tjek

Test din forståelse af praktisk refleksion.

Opsummering

Du har kombineret annotationer og refleksion for at:

  • Finde annotationer på klasser, egenskaber og funktioner
  • Læse annotationers argumenter under kørsel
  • Oprette en mini-serialiserer og en rutefordeler
  • Springe felter over med markørannotationer

Sådan bygges rigtige rammeværk.

Gratis at komme i gang

Lær Kotlin med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
51
Lektioner
203

Ofte stillede spørgsmål

Er lektionen “Praktisk reflection” gratis?

Ja — alle 3 lektioner i læringssporet Kotlin Academy, inklusive “Praktisk reflection”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Kotlin Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Praktisk reflection”?

Læs annotations dynamisk Du øver dig i Kotlin Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Kotlin Academy?

Der kræves ingen tidligere erfaring. Kotlin Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “Praktisk reflection”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Kotlin Academy-lektion?

Ja. Alle Kotlin Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Brug af annotations
  2. Definition af annotations
  3. Grundlæggende reflection
  4. Praktisk reflection
← Tilbage til Kotlin Academy