Котлин заставляет геттер / сеттер рефлексивно

Начинающий в Котлине.

Я пытаюсь создать и заполнить объекты отражением в программе. Я не могу найти эквивалентную функциональность в чистом 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) } 

Вы можете использовать отражение Kotlin, которое требует от вас добавить kotlin-reflect в зависимости от вашего проекта.

Здесь вы можете найти kotlin-reflect для Kotlin 1.0.5 или выбрать другую версию, если вы используете другую версию 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) } 

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

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

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

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

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