Вы столкнулись с этой проблемой, потому что в Java существует нечто, называемое Тип стирания . И поскольку Kotlin использует JVM, на это также влияет это ограничение. Чтобы дать TL; DR;
Универсальный тип сохраняется в файле .class
, поэтому java знает, что класс (в вашем случае List
) является универсальным. Но он не может отслеживать общий тип экземпляра. Таким образом, экземпляры List<Foo>
и List<Bar>
обрабатываются в форме raw type во время выполнения (List
). Помните, что дженерики используются только во время компиляции для обеспечения безопасности типов.
Чтобы преодолеть это ограничение, вы можете использовать перегрузку операторов в kotlin. Оператор, на который мы смотрим, это ()
, который позволяет вам вызывать любой экземпляр. Используя companion object
, мы можем даже сделать это
invoke
выглядит как конструктор и вызывается как один (MyClass()
). Ваш код может выглядеть так:
class MyClass(var foos: List<Foo>) {
companion object {
operator fun invoke(bars: List<Bar>) = MyClass(bars.map(::Foo))
}
}
Что позволяет вам назвать это просто так:
val mc1 = MyClass(foos) // calls constructor
val mc2 = MyClass(bars) // calls companion.invoke