2016-12-17 3 views
3

ここではコトリンの初心者です。Kotlinはgetter/setterを反映して呼び出します

私は、プログラムでリフレクションによってオブジェクトを作成して作成しようとします。純粋なkotlinで同等の機能を見つけることができないので、私のソリューションは以下のコードと似ていますが、java.lang.String::class.javaやintelliJのような汚れた参照を使用する必要があります。これを行うために私が行方不明になっている簡単な方法はありますか?

val jclass = myObject::class.java 
val setters = jclass.declaredMethods.filter { it.name.startsWith("set") } 
for (s in setters) { 
    val paramType = s.parameterTypes.first() 
    val data = when(paramType) { 
     java.lang.Integer::class.java -> foo 
     java.lang.Double::class.java -> bar 
     java.lang.String::class.java -> baz 
    } 
    s.invoke(myObject, data) 
} 

答えて

7

あなたは、あなたのプロジェクトへの依存関係としてkotlin-reflectを追加する必要がKotlin反射を、使用することができます。

ここでは、別のKotlinバージョンを使用している場合kotlin-reflectfor Kotlin 1.0.5またはpick another versionを見つけることができます。その後

次のように、あなたのコードを書き換えることができます。

val properties = myObject.javaClass.kotlin.memberProperties 
for (p in properties.filterIsInstance<KMutableProperty<*>>()) { 
    val data = when (p.returnType.javaType) { 
     Int::class.javaPrimitiveType, 
     Int::class.javaObjectType -> foo 
     Double::class.javaPrimitiveType, 
     Double::class.javaObjectType -> bar 
     String::class.java -> baz 
     else -> null 
    } 
    if (data != null) 
     p.setter.call(myObject, data) 
} 

をいくつかの詳細:

  • Kotlinの反射を利用してもかかわらず、このアプローチは、同様にJavaクラスと連携し、それぞれの分野とアクセッサは、hereのようにプロパティとして認識されます。

  • Javaリフレクションと同様に、memberPropertiesは、このタイプとそのすべてのスーパータイプのプロパティーを返します。public型で宣言されたすべてのプロパティを取得するには(privateのものを含むが、スーパータイプのものは含まない)、代わりにdeclaredMemberPropertiesを使用してください。

  • .filterIsInstance<KMutableProperty<*>は、変更可能なプロパティのみを返します。そのため、後でp.setterを使用できます。すべてのプロパティのgetterを反復処理する必要がある場合は、それを削除します。何KotlinでIntは、その用途に応じたJava intまたはjava.lang.Integerのいずれかにマッピングすることができるので、

  • whenブロックでは、私は、Int::class.javaPrimitiveTypeInt::class.javaObjectTypep.returnType.javaTypeを比較しました。 Kotlin 1.1では、p.returnType.classifier == Int::classをチェックするだけで十分でしょう。

関連する問題