2017-10-15 110 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

這很有效,謝謝! –