Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin Reflection Issue

I have these methods declared in Java libraries:

Engine.java:

public <T extends EntitySystem> T getSystem(Class<T> systemType)

Entity.java:

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

Now, I use these methods A LOT, and I would really like to use MyComponent::class (i.e. kotlin reflection) instead of the more verbose javaClass<MyComponent>() everywhere.

My EntitySystem and Component implementations are written in Kotlin.

So I thought I would create extension functions that take KClasses instead, but I am not quite sure how to make them work.

Something along the lines of...

public fun <C : Component> Entity.getComponent(type: KClass<out Component>): C {
    return getComponent(type.javaClass)
}

But this does not work for several reasons: The compiler says type inference failed, since javaClass returns Class<KClass<C>>. And I need Class<C>. I also don't know how to make the method properly generic.

Can anyone help me create these methods?

like image 329
user38725 Avatar asked Nov 22 '25 04:11

user38725


2 Answers

In current Kotlin (1.0), the code would be simpler as:

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

And can be called:

val comp: SomeComponent = entity.getComponent()

Where type inference will work, reify the generic type parameter (including any nested generic parameters) and call the method, which then uses the type parameter as a class reference.

like image 61
Jayson Minard Avatar answered Nov 24 '25 18:11

Jayson Minard


You should use the extension property java instead of javaClass.

Additionally You can improve your API with reified type parameters and rewrite your code like:

public inline fun <reified C : Component> Entity.getComponent(): C {
    return getComponent(C::class.java)
}
like image 42
bashor Avatar answered Nov 24 '25 18:11

bashor