Kotlin 数据类:如何使用 Kotlin 反射将属性值转换为其实际属性类型?

Kotlin data class: How to cast property value to its actual property type using Kotlin reflection?

提问人:Ivaylo Tonev 提问时间:6/16/2023 最后编辑:Ivaylo Tonev 更新时间:6/17/2023 访问量:139

问:

如何将 的值转换为其实际类型?目前,类型是,我需要将其传递给需要特定类型的函数。我使用 和 获取 是 的实例。kProperty1.get(myClassInstance!!)Any?kProperty1MyClass::class.declaredMemberProperties.firstOrNull { it.name == target }myClassInstanceMyClass

我的代码是这样的:

 val kProperty1 = MyClass::class.declaredMemberProperties.firstOrNull { it.name == propName }
     
            val valueFirst = myClassInstance1?.let { kProperty1.get(it) }
            val valueSecond = myClassInstance2?.let { kProperty1.get(it) }
            compareValues(valueFirst, valueSecond)

由于此错误,我无法调用compareValues:

Type mismatch: inferred type is Any but Comparable<*> was expected

我需要通过一个属性来比较 MyClass 的两个实例,该属性的名称和类型在编译时我不知道。

例如,此属性可以是 Long、String 或 LocalDate

Kotlin 动态 反射 投射

评论

0赞 Joffrey 6/16/2023
你能展示不起作用的代码吗?如果函数需要特定类型,那么为什么需要将此值强制转换为属性的声明类型?您只需要将值转换为函数期望的任何值

答:

1赞 Tenfour04 6/16/2023 #1

由于您唯一知道的有关该属性的信息是类型是 Comparable,因此将属性类型转换为 。即使不知道 of 是什么,只要这两个参数实际上是同一类型的 Comparable,该函数就会起作用,我们知道这是真的,因为它们来自同一个 KProperty。Comparable<*>compareValuesTComparable

val kProperty1 = MyClass::class.declaredMemberProperties
    .firstOrNull { it.name == target } as KProperty1<MyClass, Comparable<*>>?
requireNotNull(kProperty1) { "Property $target not found" }
val value1 = myClassInstance1?.let { kProperty1.get(it) }
val value2 = myClassInstance2?.let { kProperty1.get(it) }
val result = compareValues(value1, value2)

val kProperty1 = MyClass::class.declaredMemberProperties
    .firstOrNull { it.name == target } as KProperty1<MyClass, Comparable<*>>?
requireNotNull(kProperty1) { "Property $target not found" }
val value1 = myClassInstance1?.let(kProperty1::get)
val value2 = myClassInstance2?.let(kProperty1::get)
val result = compareValues(value1, value2)

评论

0赞 Ivaylo Tonev 6/17/2023
感谢您的回复,但属性的类型不是 MyClass。此属性是类的一部分,其类型类似于 String 或 Long。我需要这个属性类型。请参阅我更新的问题。
0赞 Tenfour04 6/17/2023
答案已更新。