2016-12-17 5 views
3

Новичок в Котлине здесь.Kotlin invoke 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-reflectfor Kotlin 1.0.5, или pick another version, если вы используете другую версию Kotlin.

После этого, вы можете переписать код следующим образом:

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) 
} 

Некоторые детали:

  • Несмотря на использование Котлин отражение, этот подход работает с классами Java, а также, их полей и аксессоры будут рассматриваться как свойства, как описано here.

  • Как и в случае с отражением Java, memberProperties возвращает public свойства этого типа и все его супертипы. Чтобы получить все свойства, объявленные в типе (включая private, но не те из супертипов), вместо этого используйте declaredMemberProperties.

  • .filterIsInstance<KMutableProperty<*> возвращает только изменчивые свойства, так что вы можете использовать их p.setter позже. Если вам нужно выполнить итерацию по геттерам всех свойств, удалите его.

  • В when блоке, я сравнил p.returnType.javaType с Int::class.javaPrimitiveType и Int::class.javaObjectType, потому что Int в Котлин могут быть отображены в любой Java int или java.lang.Integer в зависимости от его использования. В Kotlin 1.1 достаточно проверить p.returnType.classifier == Int::class.

Смежные вопросы