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

Mik*_*der 8 java generics interop kotlin

我可以实例化一个在Kotlin中使用递归泛型的具体Java类,如果是,那么如何?

细节

我试图实例化一个使用递归泛型的Java类,类似于下面的例子.我找到了一个解决方法,将Java类包装在一个新类中,但感觉就像我正在回避一个我应该能够直接处理的问题.

具有递归泛型的Java类

public class MyLegacyClass<T extends MyLegacyClass<T>> {
    // implementation ...
}
Run Code Online (Sandbox Code Playgroud)

它是如何在Java中实例化的

// In Java we just ignore the generic type...
MyLegacyClass myLegacyClass = new MyLegacyClass();
Run Code Online (Sandbox Code Playgroud)

尝试在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()
}
Run Code Online (Sandbox Code Playgroud)

Kotlin解决方法

class MyLegacyClassWrapper : MyLegacyClass<MyLegacyClassWrapper>()

class myClass {
    val x: MyLegacyClass<MyLegacyClassWrapper> = MyLegacyClassWrapper()
}
Run Code Online (Sandbox Code Playgroud)

Gio*_*oli 7

我可以在Kotlin中实例化一个使用递归泛型的具体Java类吗?如果是的话怎么样?

不,你不能.问题与差异有关.

这个Java类:

public class MyLegacyClass<T extends MyLegacyClass<T>> {}
Run Code Online (Sandbox Code Playgroud)

等于这个Kotlin类:

class MyLegacyClass<T : MyLegacyClass<T>>
Run Code Online (Sandbox Code Playgroud)

这是不变的在它的参数T.你需要一个协变类型,所以,在这种情况下:

class MyLegacyClass<out T : MyLegacyClass<T>>
Run Code Online (Sandbox Code Playgroud)

但是,由于Java的互操作性,如果不创建新的Kotlin类,就无法做到这一点.

如果可能的话,我会将类移动MyLegacyClass到其参数中的Kotlin协变T,否则,您的方法是正确的.

  • @MikeRylander它看起来像:`val x = MyLegacyClass <MyLegacyClass <*>>()` (4认同)
  • @MikeRylander完全正确 (3认同)
  • 您引用的Java互操作性问题是Kotlin将其解释为不变而不是协变? (2认同)