Как использовать reified в Kotlin?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Reified Type Parameters в Kotlin
Reified — это модификатор в Kotlin для встроенных функций (inline), который позволяет получить доступ к типу параметра на этапе исполнения. Это решение проблемы типов в Java, где информация о типах стирается на compile-time (type erasure).
Проблема Type Erasure
В Java и обычном Kotlin типы удаляются после компиляции:
// ❌ Это не сработает
fun <T> parseJson(json: String): T {
val type = T::class // Ошибка! T неизвестен в runtime
return JSON.parse(json, type)
}
Почему? Потому что T — это только информация для компилятора. В байт-коде её нет.
Решение с Reified
Reified сохраняет информацию о типе благодаря inline-функциям:
inline fun <reified T> parseJson(json: String): T {
val type = T::class // ✅ Работает!
return when (type) {
String::class -> json as T
Int::class -> json.toInt() as T
else -> JSON.parse(json, type)
}
}
// Использование
val name: String = parseJson("{\"name\": \"Иван\"}") // type сохраняется
val id: Int = parseJson("42")
Как это работает
Когда компилятор видит inline функцию, он копирует её код непосредственно в место вызова:
// На этапе инлайнинга компилятор знает конкретный тип
parseJson<User>(json) // Компилятор вставляет parseJson с T = User
parseJson<String>(json) // Компилятор вставляет parseJson с T = String
Потому что инлайнинг происходит при компиляции, а не при исполнении, информация о типе доступна.
Реальные примеры
1. Безопасная передача типов
inline fun <reified T> Intent.getSerializableExtra(key: String): T? {
return getSerializableExtra(key) as? T
}
// Использование
val user: User? = intent.getSerializableExtra("user")
2. Работа с SharedPreferences
inline fun <reified T> SharedPreferences.get(key: String, default: T): T {
return when (T::class) {
String::class -> getString(key, default as String) as T
Int::class -> getInt(key, default as Int) as T
Boolean::class -> getBoolean(key, default as Boolean) as T
else -> default
}
}
val name = prefs.get("name", "") // Компилятор автоматически поймёт String
val count = prefs.get("count", 0) // Компилятор поймёт Int
3. Фильтрация коллекций
inline fun <reified T> List<Any>.filterIsInstance(): List<T> {
return filter { it is T }.map { it as T }
}
val items: List<Any> = listOf(1, "два", 3.0, "четыре")
val strings: List<String> = items.filterIsInstance() // Только строки
Ограничения Reified
- Только для inline функций: reified не работает с обычными функциями
- Нет доступа к параметрам типа:
Tвидна, аT<U>— нет - Нельзя вызывать из Java: inline функции видны только из Kotlin
- Увеличивает размер кода: каждый вызов копирует функцию
// ❌ Ошибка
fun <reified T> notInline(): T { } // Reified требует inline!
// ❌ Ошибка
inline fun <reified T> complex(): List<T> {
val paramType = T::class.typeParameters[0] // Нет параметров!
}
Когда использовать
- Работа с типами: JSON парсинг, сериализация
- Фильтрация и кастинг: filterIsInstance, as?
- Рефлексия: T::class, T::class.java
- Generic операции: создание объектов по типу
Вывод: Reified — мощный инструмент Kotlin для работы с типами, особенно полезен в Android разработке для работы с Intent, SharedPreferences и сериализации.