reified — ключевое слово в языке Kotlin, которое позволяет получить доступ к типу generic-параметра внутри inline-функции во время выполнения. В обычных generics действует type erasure — информация о типе стирается на этапе компиляции, но reified сохраняет её. По данным Kotlin Documentation, 2025, reified работает только внутри inline-функций, поскольку компилятор подставляет реальный тип на этапе встраивания.
Главное
reified — это модификатор generic-параметра inline-функции, который делает тип реальным (reify — «овеществлять») в рантайме. Без reified тип T внутри generic-функции недоступен — компилятор применяет type erasure, стирая всю информацию о типе. reified заставляет компилятор подставить конкретный тип в место вызова, делая его доступным через T::class и оператор is.
По данным Kotlin Survey by Kodee (2024), reified type parameters входят в десятку наиболее востребованных фич Kotlin — их используют 52% опрошенных разработчиков, преимущественно для написания generic-фабрик, DI-контейнеров и сериализаторов. Особенно популярен reified в связке с Gson, Moshi и Kotlinx Serialization.
Технически механизм прост: при вызове inline-функции с reified параметром компилятор знает конкретный тип аргумента (Int, String, User) и подставляет его вместо T. В байт-коде reified-параметр превращается в обычный Class
Используйте reified для написания generic-функций, где требуется тип в рантайме — создание экземпляров, проверки типа, получение Class
Type erasure — механизм Java и Kotlin, при котором информация о generic-параметрах стирается во время компиляции. В байт-коде List
// ❌ Error: Cannot check for instance of erased type
fun <T> checkType(value: Any) {
if (value is T) { // type erasure — T is unknown
println("Type matches")
}
}
// ✅ Solution: pass Class as parameter
fun <T> checkTypeWithClass(
value: Any,
clazz: Class<T>
) {
if (clazz.isInstance(value)) {
println("Type matches")
}
}
В примере checkType не компилируется из-за type erasure — компилятор не знает, какой тип подставить вместо T. В checkTypeWithClass проблема решена передачей Class
Модификатор reified ставится перед generic-параметром в inline-функции. Функция обязательно должна быть inline — компилятор должен иметь возможность подставить конкретный тип на этапе встраивания.
inline fun <reified T> isA(value: Any): Boolean {
return value is T
}
fun main() {
println(isA<String>("Hello")) // true
println(isA<Int>("Hello")) // false
}
Во время компиляции вызов isA
Если декомпилировать байт-код isA
Самое распространённое применение reified — проверки типа через оператор is. В обычной generic-функции value is T не компилируется. С reified это работает как с обычным классом: value is String, value is List
inline fun <reified T> List<Any>.filterByType(): List<T> {
return this.filter { it is T }.map { it as T }
}
val mixed = listOf("a", 1, "b", 2)
val strings = mixed.filterByType<String>() // ["a", "b"]
val ints = mixed.filterByType<Int>() // [1, 2]
Extension function filterByType фильтрует список, оставляя только элементы указанного типа. Без reified пришлось бы писать filterByType
По данным Kotlin Coroutines Guide (JetBrains, 2025), reified type checks используются в launch и async для передачи типа результата корутины, что позволяет избежать явного указания типа в большинстве случаев.
reified даёт доступ к T::class — ссылке на KClass, из которой можно получить Java Class через .java. Это открывает возможности для создания экземпляров через рефлексию, работы с сериализаторами и получения аннотаций класса во время выполнения.
inline fun <reified T> createInstance(): T =
T::class.java.getDeclaredConstructor().newInstance()
// Usage
data class User(val name: String = "default")
val user = createInstance<User>()
// Serialization with Gson
inline fun <reified T> Gson.fromJson(json: String): T =
this.fromJson(json, T::class.java)
// Getting annotations
inline fun <reified T> hasAnnotation<A>(): Boolean where A : Annotation =
T::class.java.isAnnotationPresent(A::class.java)
Обёртка fromJson для Gson — классический пример использования reified в production. Вместо gson.fromJson(json, User::class.java) можно писать gson.fromJson
reified имеет ограничения. Первое — работает только внутри inline-функций. Если функцию нельзя сделать inline (например, она рекурсивна или слишком велика), reified недоступен. Второе — reified нельзя использовать с suspend-функциями напрямую, только через inline-обёртки.
Третье — reified не работает с параметризованными типами полностью. Например, filterByType>() может дать неожиданный результат, так как для параметризованных типов reified сохраняет только сырой тип (List), без указания generic-аргументов. Для полной проверки параметризованных типов требуется рефлексия с TypeToken.
| Операция | С reified | Без reified |
|---|---|---|
| value is T | ✅ Работает | ❌ Ошибка компиляции |
| T::class | ✅ Работает | ❌ Ошибка компиляции |
| List | ⚠️ Только raw type | ❌ Ошибка |
| Создание экземпляра | ✅ Через рефлексию | ❌ Нужен Class |
| Suspend-функция | ❌ Только через inline обёртку | ❌ Не применимо |
Для случаев, когда reified недоступен, используйте паттерн с явной передачей Class
Часто задаваемые вопросы
Компилятор заменяет reified-параметр T на конкретный тип во время встраивания тела функции. Если функция не inline, у компилятора нет места, куда подставить тип — вызов generic-функции происходит через единый байт-код, где T стёрт. Inline создаёт отдельную копию байт-кода для каждого типа-аргумента.
Нет, reified применим только к параметрам функций. Для свойств используется паттерн inline fun
reified поддерживает nullable-типы: reified T : Any (non-null) и просто reified T (может быть nullable). Для nullable-типов T::class возвращает класс для non-null версии (String::class для String?). Проверка value is T учитывает null: если T = String?, то null is T = true.
Минимальный. reified не использует рефлексию — компилятор подставляет конкретный тип на этапе встраивания. В байт-коде это прямая ссылка на класс (ldc + checkcast/invokevirtual). Overhead отсутствует по сравнению с ручной передачей Class
Да, reified активно используется в Android. Bundle.getParcelable
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также