Can I instantiate a concrete Java class that uses recursive generics in Kotlin, if so then how?
Details
I am trying to instantiate a Java class that uses recursive generics similar to the example below. I found a work around for wrapping the Java class in a new class, but that feels like I am sidestepping a problem that I should be able to handle directly.
Java Class With Recursive Generics
public class MyLegacyClass<T extends MyLegacyClass<T>> {
// implementation ...
}
How it is Instantiated in Java
// In Java we just ignore the generic type...
MyLegacyClass myLegacyClass = new MyLegacyClass();
Failed Attempts to Instantiate in Kotlin
class myClass {
// Error: One type argument expected for class...
val x: MyLegacyClass = MyLegacyClass()
// Still 'Error: One type argument expected for class..' You start to see the problem here.
val y: MyLegacyClass<MyLegacyClass<MyLegacyClass<MyLegacyClass>>> = MyLegacyClass()
}
Kotlin workaround
class MyLegacyClassWrapper : MyLegacyClass<MyLegacyClassWrapper>()
class myClass {
val x: MyLegacyClass<MyLegacyClassWrapper> = MyLegacyClassWrapper()
}
Can I instantiate a concrete Java class that uses recursive generics in Kotlin? if so then how?
No, you can't. The problem is related to variance.
This Java class:
public class MyLegacyClass<T extends MyLegacyClass<T>> {}
is equal to this Kotlin class:
class MyLegacyClass<T : MyLegacyClass<T>>
that is invariant in its parameter T
. You would need instead a covariant type, so, in this case:
class MyLegacyClass<out T : MyLegacyClass<T>>
But you can't do it without creating a new Kotlin class due to Java interoperability.
I would move the class MyLegacyClass
to Kotlin covariant in its parameter T
if possible, otherwise, your approach is correct.
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