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.javaType
与Int::class.javaPrimitiveType
和Int::class.javaObjectType
,因为Kotlin中的Int
可以映射到Javaint
或java.lang.Integer
具体取决于它的用法。 在Kotlin 1.1中,检查p.returnType.classifier == Int::class
就足够了。