0Pricing
Kotlin Academy · Lezione

Reflection pratica

Legga dinamicamente le annotazioni

Reflection pratica è una lezione Kotlin Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Kotlin Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Kotlin Academy include 4 lezioni in totale.

Le annotazioni incontrano la reflection

Un'annotazione con conservazione RUNTIME può essere individuata a runtime tramite reflection. Questa combinazione è alla base di serializer, validatori e dependency injection.

In questa lezione leggeremo dinamicamente le nostre annotazioni.

Leggere un'annotazione di classe

Ogni KClass espone un elenco annotations. È possibile esaminarlo per trovare un'annotazione specifica in base al tipo.

@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)
}

Helper findAnnotation

L'estensione findAnnotation è più chiara rispetto al filtraggio manuale. Restituisce l'annotazione oppure 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)
}

Annotazioni sulle proprietà

Le proprietà hanno le proprie annotazioni. Si itera su memberProperties e si esaminano le annotations di ogni proprietà.

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)
    }
}

Creare un mini serializer

Si combinano la lettura delle proprietà e le annotazioni per generare l'output. In questo caso ogni proprietà viene trasformata in una stringa chiave=valore, usando il nome della colonna quando presente.

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(", "))
}

Escludere con un marcatore

Un'annotazione marcatore può indicare le proprietà da ignorare. Se ne verifica la presenza con 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) }
}

Leggere gli argomenti delle annotazioni

Una volta ottenuta l'istanza dell'annotazione, i suoi parametri sono semplici proprietà. Li si legge come qualsiasi campo.

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)
}

Annotazioni sulle funzioni

Anche le funzioni possono essere annotate e ispezionate. I framework usano questa possibilità per individuare gli handler, ad esempio quando i test runner cercano i metodi di test.

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) }
    }
}

Guidare il comportamento

Si legge l'annotazione della route e si esegue effettivamente una chiamata. Questa è l'essenza del funzionamento dei framework di routing.

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))
        }
    }
}

Usi nel mondo reale

La reflection guidata dalle annotazioni è alla base di molte librerie:

  • Serializzazione JSON con associazione dei campi alle chiavi
  • Validazione dei vincoli
  • Routing con associazione dei percorsi agli handler
  • Dependency injection per collegare i componenti

Mantenerla mirata

È meglio confinare la reflection al codice di configurazione e dei framework, eseguito una sola volta o raramente. Quando possibile, si memorizzano nella cache i risultati. Nei percorsi ad alta frequenza per ogni richiesta, è preferibile l'elaborazione in fase di compilazione.

Verifica rapida

Verifichi la Sua comprensione dell'uso pratico della reflection.

Riepilogo

Ha combinato annotazioni e reflection per:

  • Trovare le annotazioni di classi, proprietà e funzioni
  • Leggere gli argomenti delle annotazioni a runtime
  • Creare un mini serializer e un dispatcher per il routing
  • Escludere i campi con annotazioni marcatore

È così che vengono creati i framework reali.

Domande Frequenti

La lezione «Reflection pratica» è gratuita?

Sì — il testo completo di «Reflection pratica» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Kotlin Academy, passa a CoddyKit PRO. Il corso Kotlin Academy include 4 lezioni in totale.

Cosa imparerò in «Reflection pratica»?

Legga dinamicamente le annotazioni Eserciti Kotlin Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Kotlin Academy?

Non è richiesta alcuna esperienza precedente. Kotlin Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Reflection pratica»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Kotlin Academy?

Sì. Ogni lezione Kotlin Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Utilizzo delle annotazioni
  2. Definizione delle annotazioni
  3. Nozioni di base sulla reflection
  4. Reflection pratica
← Torna a Kotlin Academy