Общий подкласс отражения Kotlin

У меня есть функция, которая принимает Class<GenericType<Constraint>>. Когда я передаю подкласс этого GenericType<Constraint>, компилятор выдает ошибку: Type Inference Failed. Expected Type Mismatch

Однако, если я бросить тип его супертипу, он работает нормально (с предупреждением). Как это сделать без кастинга?

open class Bag<T>

class IntBag: Bag<Int>()

fun testStuff(type: Class<Bag<Int>>) {
    // Do stuff
}

testStuff(IntBag::class.java) // This won't compile
testStuff(IntBag::class.java as Class<Bag<Int>>) // This compiles with a warning, but runs fine
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
238
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вам придется использовать дисперсию: fun testStuff(type: Class<out Bag<Int>>)

https://kotlinlang.org/docs/reference/generics.html

Bag<Int> эффективно отличается от IntBag, поскольку это разные классы.

Вы можете использовать typealias для IntBag следующим образом:

typealias IntBag = Bag<Int>

BUT if I cast the type to it's supertype, it runs fine (with a warning).

Что ж, он также будет «работать нормально» (в зависимости от внутренностей testStuff), если вы это сделаете.

testStuff(String::class.java as Class<Bag<Int>>)

Из-за стирания типа Class<String> можно преобразовать в Class<Anything>, и это относится и к другим универсальным типам. Но на самом деле IntBag::class.java — это Class<IntBag>, а нет — это Class<Bag<Int>>.

На самом деле значений типа Class<Bag<Int>> не существует; если вы хотите Class<any subtype of Bag<Int>>, то ответ Памелы Хилл дает синтаксис.

Другие вопросы по теме