假设您需要使用遗留库中的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>?
答案 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
在写这篇文章时,我注意到事实上java.lang.Class
实际上是一种协变类型,我认为锡兰也应该能够轻易注意到这一点。所以我创建了这个问题: