В какой функции можно использовать reified

Ответ

reified используется с inline-функциями, когда нужно сохранить информацию о типе во время выполнения. Это полезно в дженериках, где обычные типы стираются. Пример:

inline fun <reified T> parseJson(json: String): T {
    return Gson().fromJson(json, T::class.java)
}

// Использование
val user = parseJson<User>("""{"name":"John"}""")

Без reified пришлось бы передавать Class<T> отдельным параметром. Ограничение: reified работает только с inline-функциями.

Ответ 18+ 🔞

А, ну это та самая магия, когда тебе в рантайме вдруг становится доступно, какой конкретно тип ты используешь в дженериках! Без этого, как обычно, джава просто всё стирает, и ты остаешься с голой жопой и вопросом "а где мой класс?".

Вот смотри, обычная история: пишешь ты функцию, которая из JSON'а что-то парсит. Хочешь написать fun <T> parseJson(json: String): T. И тут же встаёшь в тупик — чтобы Gson (или любая другая библиотека) заработала, ей нужно передать T::class.java. А компилятор тебе такой: "Чувак, ты охуел? Какой T::class? Я про T нихуя не знаю в рантайме, всё стёрто!" И приходится городить костыль — передавать класс отдельным параметром: fun <T> parseJson(json: String, clazz: Class<T>): T. Ебать, неудобно же!

А вот с reified и inline — красота! Ты как бы говоришь компилятору: "Слушай, а давай ты не просто сгенерируешь байт-код для этой функции, а вставишь её тело прямо в место вызова, и заодно подставишь на место T реальный, конкретный тип, который я там использую?". И компилятор такой: "А, ну это другое дело, ёпта!"

inline fun <reified T> parseJson(json: String): T {
    // А вот тут уже магия — T::class.java реально работает!
    return Gson().fromJson(json, T::class.java)
}

// Вызываешь так, и всё просто пиздец как красиво
val user = parseJson<User>("""{"name":"John"}""")

Смотри, что происходит: когда компилятор видит вызов parseJson<User>, он не просто вызывает функцию. Он берёт её тело и встраивает его прямо в это место, при этом везде, где был T, ставит конкретный тип User. Получается, как будто ты написал Gson().fromJson(json, User::class.java) прямо в коде. Никакой потери информации о типе, всё на месте. Удобство — овердохуища!

Но, естественно, есть и подводный камень, ядрёна вошь. Всё это волшебство работает только с inline-функциями. Потому что механизм-то какой? Инлайнинг (встраивание тела функции) — это обязательное условие, чтобы компилятор мог подставить реальный тип на этапе компиляции. Без inline — нихуя не выйдет, будет та же самая ошибка про стирание типов.

Так что запомни: хочешь внутри дженерик-функции знать реальный класс типа T — делай функцию inline и помечай тип как reified. И тогда жизнь налаживается, а код становится чище и понятнее. Главное — не пытайся эту фишку использовать где попало, только там, где это реально нужно и оправдано.