В Kotlin дженерики (generic-параметры) по умолчанию стираются (type erasure): во время выполнения информации о типах нет. Это усложняет рефлексию, преобразование типов и чтение аннотаций по типу. Для большинства задач, это допустимо — обычные дженерики работают аналогично Java.
Inline-функции с параметром reified позволяют "заставить" компилятор "подставить" конкретный тип в месте вызова, благодаря чему функция может выполнять операции с типом на этапе выполнения (например, делать проверки, создавать новые инстансы с помощью рефлексии и т.д.). Однако reified может применяться только к параметрам в inline-функциях.
Пример сравнения:
// Обычный generic fun <T> printType(t: T) { println(t.javaClass) // Вызовет ClassCastException для List<Int> и др. } // c reified inline fun <reified T> printType(t: T) { println(T::class.simpleName) } fun main() { printType(123) // Выведет: Int printType("hello") // Выведет: String }
Практика применения: Чаще всего используется для проверки типа, кастинга, рефлексии, создания инстансов, где по-другому получить тип нельзя.
"Может ли функция с reified типом быть не inline?"
reified работает только в inline-функциях. Иначе невозможна подстановка типа на этапе компиляции.Пример неверного использования:
fun <reified T> failFunction() {} // Ошибка компиляции: reified type parameter can only be used on an inline function
Корректно:
inline fun <reified T> goodFunction() {}
История
В проекте понадобилось универсально парсить JSON-строки в любой тип через функцию с generic-параметром. Стандартная реализация через
fun <T> parse(json: String): Tне работала корректно из-за type erasure — нельзя было достать Class<T> для парсинга коллекций и обобщённых моделей. Решили через inline с reified типом — проблема исчезла.
История
Один из разработчиков пытался создавать экземпляры типа T с помощью обычного конструктора
T(), не используя inline и reified. На этапе компиляции возникала ошибка, так как информация о типе была стёрта. Переписыванием на inline fun <reified T: Any> удалось решить всё стандартными средствами языка.
История
При попытке использовать reified в обычной функции (без inline) — IDE выдала сбивающую с толку ошибку компиляции. Разработчик долго искал причину, пока не изучил документацию и не исправил функцию, добавив inline.