Ответ
Стирание типов (type erasure) — это процесс, при котором информация о generic-типах удаляется во время компиляции. В runtime JVM видит только сырые типы (raw types), что может привести к ограничениям.
Пример:
val list1: List<String> = listOf("a", "b")
val list2: List<Int> = listOf(1, 2)
// В runtime оба списка будут просто List без информации о типах
Последствия:
- Невозможно проверить generic-тип в runtime (
if (list is List<String>)— ошибка) - Приводит к unchecked cast warnings
- Для обхода используют reified-параметры в inline-функциях
Решение для проверки типов:
inline fun <reified T> checkType(item: Any) = item is T Ответ 18+ 🔞
А, ну вот, опять про эти ваши дженерики. Слушай, история смешная, но сначала объясню, как есть. Есть у нас в Котлине такая штука — стирание типов. По-русски: компилятор, когда видит List<String> и List<Int>, он их нахуй стирает. В смысле, не сам список, а информацию, что внутри. В рантайме JVM смотрит на оба этих списка и видит просто голый, ебаный List, без всяких там <String>.
Представь себе: ты пришёл в магазин, купил пакет. На пакете написано «Сахар». Ты пришёл домой, а там вместо сахара — соль. Потому что на этапе упаковки кто-то хуйни накосячил и стёр надпись. Вот примерно так и тут. Компилятор — тот самый работяга, который затирает надписи на пакетах, чтобы JVM не парилась.
Вот, смотри, пример простой:
val list1: List<String> = listOf("a", "b")
val list2: List<Int> = listOf(1, 2)
// В рантайме оба списка будут просто List, без понятия, что внутри строка или циферка.
И вот из-за этого вылезают, блядь, последствия, которые мозг выносят:
- Проверить тип нахуй нельзя. Хочешь сделать
if (list is List<String>)— получишь ошибку сразу, на этапе компиляции. Компилятор тебе скажет: «Чувак, ты чего? Я же только что стёр, какой тамString. Откуда я знаю в рантайме, что там было?» И будет прав, сука. - Предупреждения про unchecked cast. Это когда ты кастуешь что-то наугад, и компилятор тебе тихонько так говорит: «Слушай, я не уверен, что это безопасно, но если ты настоящий дебил — делай». Выглядит как
(list as List<String>). Рисковано, ёпта. - Для обхода этой хуйни придумали
reified-параметры вinline-функциях. Это такая магия, которая говорит компилятору: «Не стирай, блядь, этот тип, мне он ещё нужен будет в рантайме».
Вот решение, как тип проверить:
inline fun <reified T> checkType(item: Any) = item is T
Короче, reified — это как волшебный пинок под жопу системе типов. Он позволяет сохранить информацию о типе T и использовать её в рантайме, потому что inline-функция по сути встраивает свой код на место вызова, и компилятор уже точно знает, с каким конкретным типом он имеет дело. Без этого — нихуя не выйдет, только сырые типы и предупреждения.