Ответ
Reified позволяет сохранить информацию о типе во время выполнения в дженериках, что обычно стирается из-за type erasure в JVM. Используется с inline функциями.
Пример:
inline fun <reified T> parseJson(json: String): T {
return Gson().fromJson(json, T::class.java)
}
// Вызов
val user = parseJson<User>("{...}")
Без reified пришлось бы передавать Class<T> явно. Ограничение: работает только с inline-функциями, так как код подставляется в месте вызова с известным типом.
Ответ 18+ 🔞
А, ну это ж про reified, да? Такая штука, которая в Kotlin'е позволяет не терять тип на этапе выполнения, когда работаешь с дженериками. А то ведь JVM, хитрая жопа, по умолчанию всю эту информацию о типах просто стирает, как будто её и не было — type erasure называется. И остаёшься ты с голым кодом и вопросиками вместо типов.
А с reified ты как будто говоришь компилятору: «Слушай, ёпта, этот тип T — он мне ещё пригодится, не стирай его нахуй, оставь как есть». И компилятор такой: «Ладно, уговорил». Но есть один нюанс, Карл! Работает эта магия только с inline-функциями. Потому что когда функция inline, её код не вызывается, а прямо встраивается в место вызова. И в этот самый момент компилятор уже точно знает, какой конкретный тип ты туда подсунул, и может его подставить. Получается такой вот хитрожопый обход системы.
Вот смотри, без этой фичи пришлось бы танцевать с бубном и тащить Class<T> в аргументах, как в старые добрые времена на Java. Пиздец, неудобно же.
// Старый, скучный способ. Как будто на дворе 2002-й год.
fun <T> parseJson(json: String, clazz: Class<T>): T {
return Gson().fromJson(json, clazz)
}
// Вызов. Овердохуища boilerplate-кода.
val user = parseJson("{...}", User::class.java)
А теперь, внимание, магия:
inline fun <reified T> parseJson(json: String): T {
return Gson().fromJson(json, T::class.java) // Во! T::class.java просто работает!
}
// Вызов. Красота, одним махом. Никакого лишнего говна.
val user = parseJson<User>("{...}")
Видишь разницу? Во втором случае ты просто указываешь тип в угловых скобках, и всё. Компилятор под капотом разворачивает этот вызов, подставляет реальный класс User и вуаля — ты получаешь свой типизированный объект. Удобно, ёб твою мать, до безобразия.
Но запомни, чувак: раз только с inline, то и все ограничения inline-функций на тебя распространяются. Нельзя сохранить ссылку на такую функцию, передать её как объект высшего порядка — код должен быть встраиваемым. Но для утилитных штук вроде парсинга JSON или фабрик — это просто песня. Сам от себя охуевал, когда первый раз использовал.