Kotlin:通过反射按照定义的顺序获取数据 class 的成员

Kotlin: get members of a data class by reflection in the order they have been defined

假设以下简单示例数据 class:

data class SomeDataClass(
  var id: String,
  var name: String,
  var deleted: String
)

使用以下代码可以获取属性(并设置或获取它们的值):

import kotlin.reflect.full.memberProperties

val properties = SomeDataClass::class.memberProperties

print(properties.map { it.name })   // prints:   [deleted, id, name]

打印语句中的地图将return一个列表,其中属性名称按字母顺序排列。我需要按照它们在源代码中定义的顺序排列的列表,在这种情况下:[id, name, deleted].

这似乎不是纯粹通过反思可以实现的。我能想出的唯一解决方案是使用助手 class 定义顺序:

val SomeDataClass_Order = listOf("id", "name", "deleted")

对于一两个 classes 来说这不是问题,但是对于数百个数据 classes 来说这不是问题,其中最大的一个有将近一百个属性。

欢迎提出任何想法。我不需要详细的代码,而是提示(如解析源代码、注释等)。

如果所有属性都在主构造函数中声明,你可以“作弊”:

val propertyNames = SomeDataClass::class.primaryConstructor!!.parameters.map { it.name }

如果你想要 KPropertys:

val properties = propertyNames.map { name -> 
    SomeDataClass::class.memberProperties.find { it.name == name } 
}

遗憾的是找不到在 class 正文中声明的属性。

我不知道其他平台,但在 Kotlin/JVM 上,未指定 class 文件中属性的支持字段的生成顺序,快速实验发现顺序(至少对于我现在使用的 kotlinc 版本),顺序与声明顺序相同。所以理论上,你可以读取数据class的class文件,并找到字段。看到这个 related answer for getting the methods in order。或者,您可以使用 Java 反射,它也不保证 returned 字段的任何顺序,但是 return 它们按声明顺序“恰好”:

// not guaranteed, might break in the future
val fields = SomeDataClass::class.java.declaredFields.toList()

如果您也想按顺序获取在 class 主体内声明的属性,我建议您根本不要依赖顺序。