0Pricing
Kotlin Academy · Lekcja

Praktyczna refleksja

Odczytuj adnotacje dynamicznie

Praktyczna refleksja to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Adnotacje i refleksja

Adnotację z zachowywaniem RUNTIME można odnaleźć w czasie działania za pomocą refleksji. To połączenie jest podstawą serializatorów, walidatorów i wstrzykiwania zależności.

W tej lekcji będziemy dynamicznie odczytywać własne adnotacje.

Odczytywanie adnotacji klasy

Każdy obiekt KClass udostępnia listę annotations. Można ją przeszukać, aby znaleźć konkretną adnotację według typu.

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

Pomocnicza funkcja findAnnotation

Funkcja rozszerzająca findAnnotation jest czytelniejsza niż ręczne filtrowanie. Zwraca adnotację albo 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)
}

Adnotacje na właściwościach

Właściwości mają własne adnotacje. Iteruj po memberProperties i sprawdzaj annotations każdej właściwości.

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

Tworzenie miniaturowego serializatora

Połącz odczytywanie właściwości z adnotacjami, aby generować dane wyjściowe. W tym przypadku każda właściwość jest mapowana na ciąg znaków w formacie klucz=wartość, z użyciem nazwy kolumny, jeśli została podana.

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

Pomijanie za pomocą znacznika

Adnotacja pełniąca funkcję znacznika może oznaczać właściwości przeznaczone do pominięcia. Jej obecność sprawdzamy za pomocą 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) }
}

Odczytywanie argumentów adnotacji

Gdy ma się już instancję adnotacji, jej parametry są zwykłymi właściwościami. Należy je odczytywać tak jak każde pole.

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

Adnotacje na funkcjach

Funkcje również można oznaczać adnotacjami i poddawać inspekcji. Frameworki wykorzystują to do znajdowania obsługujących funkcji, na przykład gdy platformy testowe lokalizują metody testowe.

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

Sterowanie działaniem

Odczytaj adnotację trasy i rzeczywiście przekaż wywołanie do właściwej funkcji. Na tym właśnie polega działanie frameworków routingu.

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

Zastosowania w praktyce

Refleksja sterowana adnotacjami stanowi podstawę wielu bibliotek:

  • Serializacja JSON mapująca pola na klucze
  • Walidacja wymuszająca ograniczenia
  • Routing dopasowujący ścieżki do obsługujących je funkcji
  • Wstrzykiwanie zależności łączące komponenty

Stosuj refleksję celowo

Refleksję najlepiej ograniczać do kodu konfiguracji i frameworka, który jest uruchamiany raz lub rzadko. Jeśli to możliwe, należy buforować wyniki. W często wykonywanych ścieżkach obsługi żądań lepiej stosować przetwarzanie podczas kompilacji.

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat praktycznego zastosowania refleksji.

Podsumowanie

Połączyli Państwo adnotacje i refleksję, aby:

  • Znajdować adnotacje klas, właściwości i funkcji
  • Odczytywać argumenty adnotacji w czasie działania
  • Tworzyć miniaturowy serializator i mechanizm przekazywania tras
  • Pomijać pola oznaczone adnotacjami pełniącymi funkcję znaczników

Tak właśnie buduje się rzeczywiste frameworki.

Często zadawane pytania

Czy lekcja „Praktyczna refleksja” jest bezpłatna?

Tak — pełny tekst „Praktyczna refleksja” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Praktyczna refleksja”?

Odczytuj adnotacje dynamicznie Ćwiczysz Kotlin Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Kotlin Academy?

Nie wymagamy żadnego doświadczenia. Kotlin Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Praktyczna refleksja”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Kotlin Academy?

Tak. Każda lekcja Kotlin Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Korzystanie z adnotacji
  2. Definiowanie adnotacji
  3. Podstawy refleksji
  4. Praktyczna refleksja
← Powrót do Kotlin Academy