2017-10-15 145 views
4

我可以在Kotlin中实例化一个使用递归泛型的具体Java类吗?实例化一个在Kotlin中使用递归泛型的具体Java类

详细

我试图实例使用类似于下面的例子递归泛型的Java类。我发现了一个将Java类封装在新类中的工作,但是这感觉就像是我回避了一个我应该能够直接处理的问题。

的Java类递归泛型

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

它是如何在Java中实例化

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

失败的尝试在科特林

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() 
} 
01来实例化

科特林解决方法

class MyLegacyClassWrapper : MyLegacyClass<MyLegacyClassWrapper>() 

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

以这种方式用Java实例化它是一个坏主意,请参阅https://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html。 –

+0

@AlexeyRomanov我指出使用原始类型实例化一个通用对象是个坏主意? (如果是的话,我同意,我只是想确保我理解你的意见) –

+1

是的(作为一个更一般的声明,使用原始类型的一个具体例子是一个坏主意,除非你有要求保持与Java之前的兼容性-5代码/ JVM)。 –

回答

4

我可以实例,在科特林使用递归泛型一个具体的Java类?如果是的话那怎么样?

不,你不能。 该问题与方差有关。

class MyLegacyClass<T : MyLegacyClass<T>> 

是在它的参数T不变

该Java类:

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

等于该科特林类。您需要,而不是协变类型,所以,在这种情况下:

class MyLegacyClass<out T : MyLegacyClass<T>> 

但你不能不会产生由于Java的互操作性新科特林类做到这一点。

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

+0

如果将它转换为Kotlin并使用签名'class MyLegacyClass >',那么实例化会是什么样子? –

+3

@MikeRylander它看起来像:'val x = MyLegacyClass >()' –

+1

这很有效,谢谢! –