如何将一个扩展Java类的Ceylon类转换为Java类

时间:2013-11-27 11:34:48

标签: ceylon

假设您需要使用遗留库中的Java方法,该方法将Class作为参数:

public void takeClass(Class<? extends JavaClass> cls);

现在,假设您有一个扩展JavaClass的Ceylon类:

shared class CeylonClass() extends JavaClass() {}

现在,我怎样才能在Ceylon中使用takeClass方法,以便这样做?

javaThing.takeClass( `class CeylonClass` );

// or maybe this should work?
javaThing.takeClass( javaClass<CeylonClass>() );

如上所示,我一直在尝试模块javaClass中的函数ceylon.interop.java但没有成功...如果我javaClass<JavaClass>()那么它可以正常工作,但这对我没有用,当然。

修改

使用javaClass<CeylonClass>()时出现的错误如上所示:

argument must be assignable to parameter class of takeClass:
Class<CeylonClass> is not assignable to Class<JavaClass>?

1 个答案:

答案 0 :(得分:2)

不幸的是,这是一个需要回退到Java以添加一些粘合剂的情况。今天你不能完全用锡兰语写它。

说明

问题在于,由于Ceylon没有使用站点协方差,并且由于Ceylon类型检查器甚至不理解 Java 的使用站点协方差,因此typechecker会对此方法进行处理:< / p>

public void takeClass(Class<? extends JavaClass> cls);

好像它有更严格的签名:

public void takeClass(Class<JavaClass> cls);

此外,类型检查器将所有Java类视为不变类型。

因此,由于javaClass<CeylonClass>()生成Class<CeylonClass>,因此不会将其视为可分配给takeClass()的参数。 : - (

解决方法

解决方法是添加以下Java方法:

public static <T extends JavaClass> void takeClass2(Class<T> cls) {
    takeClass(cls);
}

现在这个方法可以从Ceylon这样调用

javaThing.takeClass2( javaClass<CeylonClass>() );

HTH

P.S。

在写这篇文章时,我注意到事实上java.lang.Class 实际上是一种协变类型,我认为锡兰也应该能够轻易注意到这一点。所以我创建了这个问题:

https://github.com/ceylon/ceylon-compiler/issues/1474