简体   繁体   English

实例化在Kotlin中使用递归泛型的具体Java类

[英]Instantiate a concrete Java class that uses recursive generics in Kotlin

Can I instantiate a concrete Java class that uses recursive generics in Kotlin, if so then how? 我可以实例化一个在Kotlin中使用递归泛型的具体Java类,如果是,那么如何?

Details 细节

I am trying to instantiate a Java class that uses recursive generics similar to the example below. 我试图实例化一个使用递归泛型的Java类,类似于下面的例子。 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类包装在一个新类中,但这感觉就像我正在回避一个我应该能够直接处理的问题。

Java Class With Recursive Generics 具有递归泛型的Java类

public class MyLegacyClass<T extends MyLegacyClass<T>> {
    // implementation ...
}

How it is Instantiated in Java 它是如何在Java中实例化的

// In Java we just ignore the generic type...
MyLegacyClass myLegacyClass = new MyLegacyClass();

Failed Attempts to Instantiate in Kotlin 尝试在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 Kotlin解决方法

class MyLegacyClassWrapper : MyLegacyClass<MyLegacyClassWrapper>()

class myClass {
    val x: MyLegacyClass<MyLegacyClassWrapper> = MyLegacyClassWrapper()
}

Can I instantiate a concrete Java class that uses recursive generics in Kotlin? 我可以在Kotlin中实例化一个使用递归泛型的具体Java类吗? if so then how? 如果是的话怎么样?

No, you can't . 不,你不能 The problem is related to variance. 问题与差异有关。

This Java class: 这个Java类:

public class MyLegacyClass<T extends MyLegacyClass<T>> {}

is equal to this Kotlin class: 等于这个Kotlin类:

class MyLegacyClass<T : MyLegacyClass<T>>

that is invariant in its parameter T . 这在参数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. 但是,由于Java的互操作性,如果不创建新的Kotlin类, 就无法做到这一点。

I would move the class MyLegacyClass to Kotlin covariant in its parameter T if possible, otherwise, your approach is correct. 如果可能的话,我会将类MyLegacyClass移动到其参数T Kotlin协变,否则,您的方法是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM