← Назад к вопросам

Для чего нужно ключевое слово reified в inline функции?

2.0 Middle🔥 141 комментариев
#Kotlin основы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Ключевое слово 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 разработки, особенно в работе с сериализацией, навигацией и работой с коллекциями.

Для чего нужно ключевое слово reified в inline функции? | PrepBro