Manuel Pérez Alcolea
06/25/2021, 3:46 AMMyClass
and an interface MyInterface
and have several classes extending and implementing them, Kotlin infers both the class and the interface in generic types. For example val list = listOf(ImplemA(), implemB())
contains objects that are MyClass
and comply with MyInterface
. IDEA describes the bound as <{MyClass & MyInterface}>
in that case. Can I specify a type like that explicitly, without creating a new class? What's the catch?Dave K
06/25/2021, 3:54 AMIf the same type parameter needs more than one upper bound, you need a separate where -clause:
fun <T> copyWhenGreater(list: List<T>, threshold: T): List<String>
where T : CharSequence,
T : Comparable<T> {
return list.filter { it > threshold }.map { it.toString() }
}
The passed type must satisfy all conditions of the where clause simultaneously. In the above example, the T type must implement both CharSequence and Comparable.
Manuel Pérez Alcolea
06/25/2021, 4:06 AMopen class MyClass(val value: Int)
interface MyInterface {
fun someMethod()
}
class ImplA : MyClass(2), MyInterface {
override fun someMethod() {
println("I am A")
}
}
class ImplB : MyClass(5), MyInterface {
override fun someMethod() {
println("I am B")
}
}
fun main() {
val impls = listOf(ImplA(), ImplB()) // this a List<{MyClass & MyInterface}>
for (ele in impls) {
ele.someMethod()
println("Its value is ${ele.value}")
}
}
I am A
Its value is 2
I am B
Its value is 5
But it works because Kotlin knows every element in the list is MyClass
and MyInterface
. What if I want to have that explicitly in the code?List
in the JVM due to type erasuredmitriy.novozhilov
06/25/2021, 6:16 AMString!
from java) and such types can be produced only by type inference
https://youtrack.jetbrains.com/issue/KT-13108