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 }
如果你想要 KProperty
s:
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 主体内声明的属性,我建议您根本不要依赖顺序。
假设以下简单示例数据 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 }
如果你想要 KProperty
s:
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 主体内声明的属性,我建议您根本不要依赖顺序。