kotlin - 收藏> 如何获取属性实例
问题描述
我目前正在使用反射在运行时使用该class.memberProperties
函数检查元素。的类型properties
是,所以我通过检查名称是否等于“nameIWant”来collection<KProperty1<I, *>>
遍历每个对象以找到我想要的对象,尽管我更希望能够通过使用上的方法,这样我就可以进行检查,例如:KProperty
KProperty
.get()
property
if (property.get(receiver) is ClassIWant) {
//Do something
}
我的代码如下所示:
val properties = request.payload::class.memberProperties
properties.forEach { property ->
run {
if (property.name.equals("nameIWant")) {
}
}
}
到目前为止,我一直在尝试.get()
在 type 上使用该方法,KProperty1
但它需要一个receiver
type参数Nothing
。我无法弄清楚我需要传递什么才能调用该.get()
方法并获取该属性的特定实例。我还检查了这里的文档:https ://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-property1/index.html但它并没有真正帮助。
解决方案
如果要获取属性的值,请将类转换为不变类型。
instance::class.memberProperties.first() // returns KProperty1<out Instance, *>
(instance::class as KClass<Instance>).memberProperties.first() // returns KProperty1<Instance, *>
如果你KClass<Instance>
是KClass<*>
,使用Any
as Instance
。
为什么KProperty.call
要Nothing
作为接收者?因为instance::class
return KClass<out Instance>
,它将协变类型参数传播到属性,它变成KProperty<out Instance, *>
,这将可能的方法接收器缩小到 Instance 的任何子类型,但是因为我们不知道哪个,我们不能安全地提供 Instance 的任何实例,因为由方差规则显示,这里将泛型类型参数限制为Nothing
,这意味着根本不可能调用该方法。
为什么::class
设计为协变的?以保证安全。这一直是一个争论不休的问题,因为它似乎有些不合逻辑。
如果您想知道属性可以返回的值的类型,请使用
property.returnType
它返回一个 KType,它是 Kotlin 版本的 Java 类型,它是一个更通用的类概念(它是类型的实现之一)。
如果您需要将 KType '转换'为 KClass,则需要执行与将 Type 转换为 Class 相同的操作,即获取类型的原始类型。原始类型是剥离了任何通用信息的类型,是的,是一种擦除类型。这样做的方法(似乎)更复杂(涉及处理每个可能的 KType/Type 实现),我建议单独检查这个问题的答案。
您将能够使用以下方法重用 Java 实现(您肯定会自己找到):
kType.javaType.covertJavaTypeToJavaClass().kotlin // returns KClass<*>
更正您的问题。如果您希望收到正确的答案,我建议使用正确的术语: *I
在您的问题中是方法接收器的类型,而不是属性的值 *collection
不是类型,Collection is
*property is ClassIWant
是不明确property.type
的,因为属性中的值的类型和property::class
只是属性实现,is
也是一个instanceof
检查,但是在反射中,您需要使用KClass.isSubclassOf
,或者在 Java 中称为type.isAssignableFrom
(注意调用顺序),这使得您的条件成为ClassIWant.isSuperclassOf(property.type.getRawType())
*instance of the property
属性具有值,而不是实例。只有类有实例。实例是值,值是(某个类的)实例,但您仍然必须说instance representing the value of the property
推荐阅读
- python - 从 keras.preprocessing API 将 tensorflow 数据集拆分为训练、测试和验证集
- python - 使用 tensorflow.keras 模型的 concurrent.futures 并行预测
- python - Pandas read_csv 不读取原始字符串
- c++ - 如何在 C++ 中将字符串从十进制代码转换为西里尔文/unicode16?
- c++ - 摆脱输入缓冲区
- java - 具有 jdbc 持久性的 Bean 管理的 EB3
- elasticsearch - 是否可以通过查询更新索引设置?
- c# - 收到“CS1503 参数 1:无法从 'Sytem.Threading.Tasks.Task 转换”的错误消息
' 到 'BookListRazor.Model.Book' - powershell - 有没有人设法通过 Azure Function App 中的 Powershell 提取所有 Azure Active Directory 用户的列表?
- excel - Excel VBA - 标题长度会导致运行时错误 1004?