Для чего нужно ключевое слово reified в inline функции?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Ключевое слово reified в inline функциях
reified — это мощный инструмент в Kotlin, который позволяет получить доступ к типам параметров на уровне runtime. Это решает проблему type erasure (стирания типов), которая приходит из Java и JVM.
Проблема type erasure
В Java и Kotlin (на JVM) типы параметров удаляются во время компиляции. Это означает, что на runtime невозможно узнать, какой конкретный тип был передан:
// Обычная функция с типом параметром
fun <T> printType(value: T) {
println(T::class) // Ошибка! T не доступен на runtime
}
// Невозможно получить информацию о типе T во время выполнения
Решение: reified в inline функции
Когда функция помечена как inline с reified типом параметром, компилятор подставляет код функции прямо в место вызова с конкретным типом. Это позволяет сохранить информацию о типе на runtime:
inline fun <reified T> printType(value: T) {
println(T::class) // Работает!
println(T::class.java.name)
}
printType("Hello") // Выведет: String
printType(42) // Выведет: Int
Как работает inline + reified
Компилятор преобразует вызов функции:
// Исходный код
inline fun <reified T> getType(): String = T::class.simpleName
val stringType = getType<String>()
val intType = getType<Int>()
// После инлайнинга (эквивалент)
val stringType = String::class.simpleName
val intType = Int::class.simpleName
Компилятор подставляет тип параметр T явно в каждое место вызова.
Практические примеры использования
1. Безопасное приведение типов (Безопасное casting)
inline fun <reified T> safeCast(obj: Any?): T? {
return if (obj is T) obj else null
}
val value: Any = "Hello"
val str: String? = safeCast(value) // Работает безопасно
val num: Int? = safeCast(value) // Вернёт null
2. Создание объектов по типу (Factory pattern)
inline fun <reified T> fromJson(json: String): T {
return Gson().fromJson(json, T::class.java)
}
data class User(val name: String, val age: Int)
val user = fromJson<User>("{'name': 'John', 'age': 30}")
3. 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
Long::class -> getLong(key, default as Long) as T
else -> throw IllegalArgumentException("Unsupported type")
}
}
// Использование
val name: String = prefs.get("user_name", "Anonymous")
val age: Int = prefs.get("user_age", 0)
4. Создание Intent с параметрами (Navigation)
inline fun <reified T : Activity> Context.startActivity(
vararg params: Pair<String, Any?>
) {
val intent = Intent(this, T::class.java)
params.forEach { (key, value) ->
when (value) {
is String -> intent.putExtra(key, value)
is Int -> intent.putExtra(key, value)
is Boolean -> intent.putExtra(key, value)
}
}
startActivity(intent)
}
// Использование
startActivity<DetailActivity>("user_id" to 123, "name" to "John")
5. Фильтрование списков по типу
inline fun <reified T> List<*>.filterByType(): List<T> {
return filterIsInstance<T>()
}
val mixed: List<Any> = listOf("text", 42, "hello", 100)
val strings = mixed.filterByType<String>() // ["text", "hello"]
val ints = mixed.filterByType<Int>() // [42, 100]
Важные ограничения
- Только в inline функциях — reified работает ТОЛЬКО с inline функциями
- Не для private функций — inline функции должны быть public
- Размер кода — каждый вызов копирует код функции, может увеличить размер APK
- Не в interface — interface методы не могут быть inline
// Ошибка: не inline
fun <reified T> normalFunction() {}
// Ошибка: private inline
private inline fun <reified T> privateInline() {}
// ОК: public inline с reified
public inline fun <reified T> goodFunction() {}
Best practices
- Используй для серьёзной логики — не добавляй reified для простых операций
- Оборачивай public функции — если нужна private логика, создай wrapper
- Осторожней с размером — inline может раздуть APK, используй разумно
- Документируй поведение — reified может быть неочевидна для новичков
reified + inline — это мощная комбинация, которая даёт Kotlin большие возможности и является неотъемлемой частью современной Kotlin разработки, особенно в работе с сериализацией, навигацией и работой с коллекциями.