Assume that I have this declaration in Java, it's okay.
abstract class Start<T extends End> {
public T end;
}
abstract class End<T extends Start> {
public T start;
}
However, it's not okay in Kotlin, since Kotlin has restriction for "cyclic" type parameter.
abstract class Start<T : End<*>> {
lateinit var end: T
}
abstract class End<T : Start<*>> {
lateinit var start: T
}
Is there any approach to solve this in Kotlin, so that I can have generic types that depend on each other?
When we define a collection with "*", it should contain the object of only that type. There should not be any mix and match between the data types inside a collection. If we use "Any", we can mix and match the data types, which means we can have multiple data types in a collection.
"Out" keyword is extensively used in Kotlin generics. Its signature looks like this − List<out T> When a type parameter T of a class C is declared out, then C can safely be a super type of C<Derived>. That means, a Number type List can contain double, integer type list.
Kotlin generic example When we call the generic method <T>printValue(list: ArrayList<T>) using printValue(stringList), the type T of method <T>printValue(list: ArrayList<T>)will be replaced by String type.
We can make generic variable using this kind of syntax: "val destinationActivity: Class<*>". Main part is "*".
It is impossible to use just one type parameter. Introducing Self
type, which is natively supported in some other languages, is necessary. However, in kotlin you will have to introduce the Self
type by yourself, because JetBrains officially turned down the request of adding self type.
abstract class Start<Self: Start<Self, T>, T: End<T, Self>> {
lateinit var end: T
}
abstract class End<Self: End<Self, T>, T: Start<T, Self>> {
lateinit var start: T
}
PS: This Self
may later induce tediously long type. Proceed with caution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With