Kotlin反射问题

3
我在Java库中声明了以下方法:
Engine.java:
public <T extends EntitySystem> T getSystem(Class<T> systemType)

Entity.java:

public <T extends Component> T getComponent(Class<T> componentClass)

现在,我经常使用这些方法,我真的很想在所有地方使用MyComponent::class(即Kotlin反射),而不是更冗长的javaClass<MyComponent>()

我的EntitySystemComponent实现是用Kotlin编写的。
所以我想创建接受KClasses的扩展函数,但我不太确定如何使它们工作。
类似于...
public fun <C : Component> Entity.getComponent(type: KClass<out Component>): C {
    return getComponent(type.javaClass)
}

但是由于几个原因,这并不起作用:编译器说类型推断失败,因为javaClass返回Class<KClass<C>>。我需要的是Class<C>。我也不知道如何使方法正确地通用。
有人能帮我创建这些方法吗?

我已经发布了一个新答案,该答案适用于当前的Kotlin,并实现了内联函数和@bashor建议的具有具体类型参数。 - Jayson Minard
2个回答

2

在当前的Kotlin(1.0)中,代码将更加简单:

public inline fun <reified C : Component> Entity.getComponent(): C {
    return getComponent(C::class)
}

并且可以被称为:

val comp: SomeComponent = entity.getComponent()

在类型推断可行的情况下,将泛型类型参数(包括任何嵌套的泛型参数)具体化并调用方法,然后使用该类型参数作为类引用。


1

您应该使用扩展属性 java 而不是 javaClass

此外,您可以通过 具体化的类型参数 来改进您的 API,并重写您的代码,如下所示:

public inline fun <reified C : Component> Entity.getComponent(): C {
    return getComponent(C::class.java)
}

公共函数 Engine.get<S : EntitySystem>(type: KClass<S>) : S { 返回 getSystem(type.java) } 似乎解决了问题。 - user38725
我已经更新到最新的 Kotlin(0.12.1230),但是 kotlin.reflect.jvm 似乎不再存在了?有人知道它是否已被重命名或其他什么情况吗? - user38725
没关系...问题似乎是Android Studio想要添加kotlin-reflect,但根本没有更新build.gradle文件... - user38725
javaClass<T>()已被弃用,请使用T::class代替。 - Jayson Minard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接