Kotlin反射 - 获取一个类的所有字段名称

26

如何获取 Kotlin 数据类的 declaredFields 列表?类似于 Java 的 getDeclaredFields()

如果可能,是否也可以过滤 publicprivate 字段?(类似于 Java 的 Modifier.isPrivate(field.getModifiers())


你对领域(即原始Java类)或属性(即JavaBean或Kotlin类)感兴趣吗?你只处理Kotlin类还是也处理Java类? - Jayson Minard
只有 Kotlin 类,但是 @hotkey 的解决方案适用于我的特定问题。 - Ivar Reukers
“这个调用没有任何文档资料”- 这里提供相关文档链接。 - Jayson Minard
我知道了,后来看到了,一开始找不到/不知道该搜索什么,所以错过了那份文档。 - Ivar Reukers
4个回答

28
也许你想要获取一个类的属性,而不是字段。可以按照以下方式完成:
MyClass::class.declaredMemberProperties

通过Java反射也可以获取字段:

MyClass::class.java.declaredFields

但在Kotlin中,字段更多的是一种实现细节,因为一些属性可能没有支持字段


关于可见性,在属性方面,您可以检查getter的可见性修饰符:
val p = MyClass::class.declaredMemberProperties.first()
val modifiers = p.javaGetter?.modifiers

注意:如果只是使用简单的private val@JvmField,则为null。然后,您可以检查p.javaField

然后,如果modifiers不为null,只需使用Modifier.isPrivate(...)进行检查。

Kotlin中的属性可以具有分别为getter和setter设置的可见性修饰符,但setter访问权限不能比getter更宽松,这实际上就是属性的可见性。


是否有可能创建 MyClass 对象,并使用 Java 反射设置这些 declaredFieldsField.name 值? - Ivar Reukers
1
如果Java类有一个字段是public static final String,我能获取它的字符串值吗? - quangkid
使用import kotlin.reflect.full.declaredMemberProperties,以防万一IDE没有建议。 - klenium

4

关于Kotlin反射,确实有文档可供参考:反射的概述API文档,其中包括KClass.members函数。你还可以跳转到该方法的声明,并查看源代码中的文档说明。


3
使用 MyClass::class.java.declaredFields 或它的实例:myObject::class.java.declaredFields

0

最好的方法是检查哪些成员是KProperty1<*,*>的子类。

MyClass::class.members.filter{
  when(it){
    is KProperty1<*,*> -> true
    else -> false
  }
}.map{ it as KProperty<MyClass,*> }

为什么要使用KProperty1?如文档所述(https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-property/),KProperty0用于静态属性(如在包的根目录中定义的属性)。KProperty2用于扩展属性,而KProperty1用于字段。
如果您只想要已声明的属性,则可以与Java反射混合使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接