Kotlin反射地调用getter / setter

初学者在Kotlin这里。

我尝试通过在程序中反射来创建和填充对象。 我无法在纯kotlin中找到等价的功能,所以我的解决方案类似于下面的代码,它的工作正常,但需要使用像java.lang.String::class.java这样的dirty参考,可以理解,似乎不喜欢这个。 有没有更简单的方法,我失踪要做到这一点?

 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 1.0.5的 kotlin-reflect ,或者如果你使用不同的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 。 如果您需要迭代所有属性的getter,请将其删除。

  • when块中,我将p.returnType.javaTypeInt::class.javaPrimitiveTypeInt::class.javaObjectType ,因为Kotlin中的Int可以映射到Java intjava.lang.Integer具体取决于它的用法。 在Kotlin 1.1中,检查p.returnType.classifier == Int::class就足够了。