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
- Korzystanie z adnotacji
- Definiowanie adnotacji
- Podstawy refleksji
- Praktyczna refleksja