Wymazywanie typów i parametry typów reified
Używaj reified z funkcjami inline, aby uzyskiwać informacje o typach w czasie działania.
Wymazywanie typów i parametry typów reified 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.
Czym jest wymazywanie typów?
W czasie działania JVM wymazuje argumenty typów generycznych. List<String> i List<Int> są wtedy po prostu obiektami typu List. Ogranicza to operacje na typach generycznych dostępne w czasie działania.
fun main() {
val strings: List<String> = listOf("a", "b")
val ints: List<Int> = listOf(1, 2)
println(strings.javaClass == ints.javaClass) // true: both ArrayList
println(strings is List<*>) // OK with star
// println(strings is List<String>) // warning: unchecked cast
}Problem: nie można sprawdzać wymazanych typów
Nie można używać is z konkretnym argumentem typu generycznego, ponieważ informacje o typie znikają w czasie działania.
fun checkType(obj: Any) {
// This works:
if (obj is List<*>) println("It's a list of something")
// This doesn't compile cleanly:
// if (obj is List<String>) println("It's a list of strings") // unchecked
}
fun main() {
checkType(listOf("hello"))
checkType(42)
}Podsumowanie funkcji inline
inline kopiuje treść funkcji do miejsca wywołania podczas kompilacji. To właśnie umożliwia użycie reified — argument typu również jest podstawiany w miejscu wywołania.
inline fun <T> myRun(block: () -> T): T = block()
fun main() {
val result = myRun { 42 }
println(result) // 42
// The compiler inlines the lambda body — no object allocation
}reified: dostęp do T w czasie działania
Połączenie inline z reified zachowuje argument typu w miejscu wywołania, umożliwiając użycie is, as i ::class dla T.
inline fun <reified T> isInstance(value: Any): Boolean = value is T
fun main() {
println(isInstance<String>("hello")) // true
println(isInstance<Int>("hello")) // false
println(isInstance<List<*>>(listOf())) // true
}Pobieranie KClass typu T
Dzięki reified T można uzyskać T::class w czasie działania — co normalnie jest niemożliwe w funkcjach generycznych.
inline fun <reified T> classNameOf(): String = T::class.simpleName ?: "Unknown"
fun main() {
println(classNameOf<String>()) // String
println(classNameOf<Int>()) // Int
println(classNameOf<List<*>>()) // List
}Bezpieczne rzutowanie z reified
Użyj reified, aby napisać bezpieczną typowo funkcję pomocniczą do rzutowania, która zamiast zgłaszać wyjątek zwraca null.
inline fun <reified T> Any?.safeCast(): T? = this as? T
fun main() {
val obj: Any = "Hello"
val s: String? = obj.safeCast<String>()
val i: Int? = obj.safeCast<Int>()
println(s) // Hello
println(i) // null
}Analizowanie JSON z reified
Biblioteki takie jak Gson lub kotlinx.serialization używają reified do wywnioskowania typu docelowego w miejscu wywołania bez jawnego przekazywania obiektów Class.
import com.google.gson.Gson
// Simulated without real Gson:
inline fun <reified T> parseJson(json: String): T {
return Gson().fromJson(json, T::class.java)
}
// Usage:
// val user: User = parseJson<User>("""{"name":"Alice"}""")reified z filterIsInstance
Funkcja filterIsInstance<T>() z biblioteki standardowej używa reified do filtrowania listy do określonego typu bez ręcznego rzutowania.
fun main() {
val mixed: List<Any> = listOf(1, "hello", 2.5, "world", true)
val strings = mixed.filterIsInstance<String>()
val ints = mixed.filterIsInstance<Int>()
println(strings) // [hello, world]
println(ints) // [1]
}Nie można używać reified w funkcjach innych niż inline
reified działa tylko z funkcjami inline. Próba użycia go bez inline powoduje błąd kompilacji.
// Error:
// fun <reified T> broken(): String = T::class.simpleName ?: "?"
// Must be inline:
inline fun <reified T> correct(): String = T::class.simpleName ?: "?"
fun main() {
println(correct<Double>()) // Double
}reified i refleksja
Połącz reified z refleksją, aby dynamicznie sprawdzać właściwości lub adnotacje typu bez powtarzalnych parametrów Class.
inline fun <reified T : Any> properties(): List<String> =
T::class.members.map { it.name }
data class Point(val x: Int, val y: Int)
fun main() {
println(properties<Point>()) // [x, y, component1, component2, copy, equals, hashCode, toString]
}Praktyka: bezpieczny typowo lokalizator usług
Użyj reified do zbudowania lokalizatora usług, który mapuje KClass na instancje, zapewniając lekkie DI bez procesorów adnotacji.
val registry = mutableMapOf<kotlin.reflect.KClass<*>, Any>()
inline fun <reified T : Any> register(instance: T) { registry[T::class] = instance }
@Suppress("UNCHECKED_CAST")
inline fun <reified T : Any> resolve(): T = registry[T::class] as T
class Logger { fun log(msg: String) = println("[LOG] $msg") }
fun main() {
register(Logger())
resolve<Logger>().log("Service located!")
}Ograniczenia reified
Parametrów typu reified nie można używać w kontekstach innych niż inline, nie można przechowywać typu do późniejszego użycia ani przekazywać ich do funkcji innych niż inline, które potrzebują typu w czasie działania.
inline fun <reified T> foo() {
val clazz = T::class // OK here
// bar(clazz) // must pass clazz explicitly to non-inline funs
println(clazz.simpleName)
}
fun bar(clazz: kotlin.reflect.KClass<*>) = println(clazz.simpleName)
fun main() { foo<String>() }Szybkie sprawdzenie
Co jest wymagane, aby parametr typu był reified?
Podsumowanie
Wymazywanie typów usuwa informacje o typach generycznych w czasie działania. reified w funkcjach inline zachowuje argument typu w miejscu wywołania, umożliwiając użycie is, as, ::class i refleksji dla T — bez ręcznego przekazywania obiektów Class.
Często zadawane pytania
Czy lekcja „Wymazywanie typów i parametry typów reified” jest bezpłatna?
Tak — pełny tekst „Wymazywanie typów i parametry typów reified” 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 „Wymazywanie typów i parametry typów reified”?
Używaj reified z funkcjami inline, aby uzyskiwać informacje o typach w czasie działania. Ć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 „Wymazywanie typów i parametry typów reified”?
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
- Funkcje generyczne i ograniczenia typów za pomocą where
- Wariancja deklarowana w miejscu deklaracji: in i out
- Projekcja gwiazdkowa i kiedy używać *
- Wymazywanie typów i parametry typów reified